summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-01-22 15:33:06 +0100
committerStefan Wintermeyer <stefan.wintermeyer@amooma.de>2013-01-22 15:33:06 +0100
commit39aa7132ceed3d4beab3a9b828e571bbfc67c07e (patch)
tree6c88289c9f99be0af8635636fcdf64102090e5ec
parent5ad8203ce4f1bfea997960d0b52c626dea24b944 (diff)
parent6f69c1a85055ec7c2515719d79d2a7a4e60cec50 (diff)
Merge branch 'develop'5.1-beta1
-rw-r--r--.gitignore3
-rw-r--r--Gemfile34
-rw-r--r--Gemfile.lock220
-rw-r--r--app/assets/images/amooma-logo.pngbin1314 -> 0 bytes
-rw-r--r--app/assets/images/bg-body.pngbin1768 -> 0 bytes
-rw-r--r--app/assets/images/gradients/light-to-dark-blue-x63.pngbin187 -> 0 bytes
-rw-r--r--app/assets/images/gradients/white-gray-x29-reverse.pngbin123 -> 0 bytes
-rw-r--r--app/assets/images/gradients/white-gray-x29.pngbin126 -> 0 bytes
-rw-r--r--app/assets/images/gradients/white-texture-x63.pngbin6927 -> 0 bytes
-rw-r--r--app/assets/images/icons/glyphicons-halflings-white.pngbin0 -> 8777 bytes
-rw-r--r--app/assets/images/icons/glyphicons-halflings.pngbin0 -> 12799 bytes
-rw-r--r--app/assets/images/logo.pngbin7490 -> 0 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom300.pngbin0 -> 51018 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom320.pngbin0 -> 66491 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom360.pngbin0 -> 68592 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom370.pngbin0 -> 68924 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom820.pngbin0 -> 60875 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom821.pngbin0 -> 60875 bytes
-rw-r--r--app/assets/images/phones/snom/Visio_snom870.pngbin0 -> 59457 bytes
-rw-r--r--app/assets/images/stubs/user-36x.jpgbin2093 -> 0 bytes
-rw-r--r--app/assets/images/user.pngbin4800 -> 0 bytes
-rw-r--r--app/assets/javascripts/application.js19
-rw-r--r--app/assets/javascripts/bootstrap.js2025
-rw-r--r--app/assets/javascripts/config_siemens.js.coffee3
-rw-r--r--app/assets/javascripts/core.coffee5
-rw-r--r--app/assets/javascripts/phones.js.coffee3
-rw-r--r--app/assets/javascripts/softkeys.js.coffee25
-rw-r--r--app/assets/javascripts/trigger.js.coffee (renamed from app/assets/javascripts/api/rows.js.coffee)0
-rw-r--r--app/assets/javascripts/vendor/autoresize.jquery.js94
-rwxr-xr-xapp/assets/javascripts/vendor/fancybox/jquery.easing-1.3.pack.js205
-rwxr-xr-xapp/assets/javascripts/vendor/fancybox/jquery.fancybox-1.3.4.pack.js46
-rwxr-xr-xapp/assets/javascripts/vendor/fancybox/jquery.mousewheel-3.0.4.pack.js14
-rw-r--r--app/assets/javascripts/vendor/html5boilerplate.js20
-rwxr-xr-xapp/assets/javascripts/vendor/jquery-1.6.2.min.js18
-rw-r--r--app/assets/javascripts/vendor/jquery.condom.js52
-rw-r--r--app/assets/javascripts/vendor/jquery.easy-slider-1.7.js225
-rw-r--r--app/assets/javascripts/vendor/jquery.survival-kit.coffee36
-rw-r--r--app/assets/javascripts/vendor/jquery.tmpl.js486
-rwxr-xr-xapp/assets/javascripts/vendor/modernizr-2.0.6.min.js1116
-rw-r--r--app/assets/stylesheets/app/layouts/_app.scss24
-rw-r--r--app/assets/stylesheets/app/layouts/_conference.scss136
-rw-r--r--app/assets/stylesheets/app/layouts/_phone-book-entry.scss176
-rw-r--r--app/assets/stylesheets/app/pages/_phone_book.scss25
-rw-r--r--app/assets/stylesheets/app/shared/_contents.scss374
-rw-r--r--app/assets/stylesheets/app/shared/_footers.scss90
-rw-r--r--app/assets/stylesheets/app/shared/_handheld.scss25
-rw-r--r--app/assets/stylesheets/app/shared/_headers.scss145
-rw-r--r--app/assets/stylesheets/app/shared/_ie.scss7
-rw-r--r--app/assets/stylesheets/app/shared/_media.scss16
-rw-r--r--app/assets/stylesheets/app/shared/_print.scss17
-rw-r--r--app/assets/stylesheets/application.css15
-rw-r--r--app/assets/stylesheets/application.css.scss117
-rw-r--r--app/assets/stylesheets/bootstrap/bootstrap-responsive.css1088
-rw-r--r--app/assets/stylesheets/bootstrap/bootstrap.css.erb5893
-rw-r--r--app/assets/stylesheets/gemeinschaft-generic.css.scss13
-rw-r--r--app/assets/stylesheets/scaffolds.css.scss56
-rw-r--r--app/assets/stylesheets/trigger.css.scss (renamed from app/assets/stylesheets/api/rows.css.scss)2
-rw-r--r--app/assets/stylesheets/vendor/README1
-rw-r--r--app/assets/stylesheets/vendor/boilerplate-1.0/README15
-rw-r--r--app/assets/stylesheets/vendor/boilerplate-1.0/_reset.scss37
-rw-r--r--app/assets/stylesheets/vendor/boilerplate-1.0/_styles.scss171
-rw-r--r--app/assets/stylesheets/vendor/boilerplate-2.0/README16
-rw-r--r--app/assets/stylesheets/vendor/boilerplate-2.0/_styles.scss209
-rw-r--r--app/assets/stylesheets/vendor/easy-slider/_numeric.scss44
-rw-r--r--app/assets/stylesheets/vendor/facebox/_facebox.scss85
-rw-r--r--app/assets/stylesheets/vendor/fancy-box/README4
-rwxr-xr-xapp/assets/stylesheets/vendor/fancy-box/_fancy-box.scss336
-rw-r--r--app/assets/stylesheets/vendor/fancy-buttons/README3
-rw-r--r--app/assets/stylesheets/vendor/fancy-buttons/_fancy-buttons.scss195
-rw-r--r--app/assets/stylesheets/vendor/fancy-buttons/_fancy-gradient.scss28
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_blog.scss99
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_effects.scss97
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_forms.scss313
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_headers.scss36
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_images.scss121
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_lists.scss37
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_loader.scss11
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_navigation.scss230
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_secure.scss3
-rw-r--r--app/assets/stylesheets/vendor/survival-kit/_tools.scss267
-rw-r--r--app/controllers/api/rows_controller.rb2
-rw-r--r--app/controllers/application_controller.rb4
-rw-r--r--app/controllers/call_forwards_controller.rb4
-rw-r--r--app/controllers/call_histories_controller.rb4
-rw-r--r--app/controllers/call_routes_controller.rb75
-rw-r--r--app/controllers/conferences_controller.rb2
-rw-r--r--app/controllers/config_siemens_controller.rb26
-rw-r--r--app/controllers/config_siemens_sort_controller.rb371
-rw-r--r--app/controllers/config_snom_controller.rb65
-rw-r--r--app/controllers/fax_accounts_controller.rb4
-rw-r--r--app/controllers/gateway_parameters_controller.rb44
-rw-r--r--app/controllers/gateway_settings_controller.rb44
-rw-r--r--app/controllers/gateways_controller.rb57
-rw-r--r--app/controllers/gemeinschaft_setups_controller.rb39
-rw-r--r--app/controllers/gs_nodes_controller.rb2
-rw-r--r--app/controllers/gs_parameters_controller.rb44
-rw-r--r--app/controllers/gui_functions_controller.rb12
-rw-r--r--app/controllers/page_controller.rb7
-rw-r--r--app/controllers/phone_book_entries_controller.rb2
-rw-r--r--app/controllers/phone_books_controller.rb4
-rw-r--r--app/controllers/phone_numbers_controller.rb17
-rw-r--r--app/controllers/phones_controller.rb9
-rw-r--r--app/controllers/route_elements_controller.rb67
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/controllers/sip_accounts_controller.rb22
-rw-r--r--app/controllers/tenants_controller.rb19
-rw-r--r--app/controllers/trigger_controller.rb11
-rw-r--r--app/controllers/user_groups_controller.rb2
-rw-r--r--app/controllers/users_controller.rb4
-rw-r--r--app/controllers/voicemail_messages_controller.rb6
-rw-r--r--app/helpers/call_routes_helper.rb2
-rw-r--r--app/helpers/gateway_parameters_helper.rb2
-rw-r--r--app/helpers/gateway_settings_helper.rb2
-rw-r--r--app/helpers/gateways_helper.rb2
-rw-r--r--app/helpers/gs_parameters_helper.rb2
-rw-r--r--app/helpers/route_elements_helper.rb2
-rw-r--r--app/helpers/trigger_helper.rb2
-rw-r--r--app/mailers/notifications.rb8
-rw-r--r--app/models/ability.rb11
-rw-r--r--app/models/access_authorization.rb4
-rw-r--r--app/models/api/row.rb2
-rw-r--r--app/models/automatic_call_distributor.rb4
-rw-r--r--app/models/call_forward.rb2
-rw-r--r--app/models/call_route.rb241
-rw-r--r--app/models/callthrough.rb2
-rw-r--r--app/models/conference.rb6
-rw-r--r--app/models/conference_invitee.rb2
-rw-r--r--app/models/fax_document.rb4
-rw-r--r--app/models/gateway.rb35
-rw-r--r--app/models/gateway_parameter.rb19
-rw-r--r--app/models/gateway_setting.rb31
-rw-r--r--app/models/gemeinschaft_setup.rb21
-rw-r--r--app/models/gs_cluster_sync_log_entry.rb4
-rw-r--r--app/models/gs_parameter.rb35
-rw-r--r--app/models/hunt_group.rb10
-rw-r--r--app/models/phone.rb7
-rw-r--r--app/models/phone_book.rb2
-rw-r--r--app/models/phone_book_entry.rb2
-rw-r--r--app/models/phone_model.rb2
-rw-r--r--app/models/phone_number.rb16
-rw-r--r--app/models/phone_number_range.rb2
-rw-r--r--app/models/route_element.rb26
-rw-r--r--app/models/sip_account.rb6
-rw-r--r--app/models/tenant.rb29
-rw-r--r--app/models/user.rb4
-rw-r--r--app/views/access_authorizations/_index_core.html.haml6
-rw-r--r--app/views/access_authorizations/edit.html.haml2
-rw-r--r--app/views/access_authorizations/index.html.haml2
-rw-r--r--app/views/access_authorizations/new.html.haml2
-rw-r--r--app/views/access_authorizations/show.html.haml2
-rw-r--r--app/views/acd_agents/_index_core.html.haml6
-rw-r--r--app/views/acd_agents/edit.html.haml2
-rw-r--r--app/views/acd_agents/index.html.haml2
-rw-r--r--app/views/acd_agents/new.html.haml2
-rw-r--r--app/views/acd_agents/show.html.haml2
-rw-r--r--app/views/acd_callers/_index_core.html.haml6
-rw-r--r--app/views/acd_callers/index.html.haml2
-rw-r--r--app/views/acd_callers/show.html.haml2
-rw-r--r--app/views/addresses/_index_core.html.haml6
-rw-r--r--app/views/addresses/edit.html.haml2
-rw-r--r--app/views/addresses/index.html.haml2
-rw-r--r--app/views/addresses/new.html.haml2
-rw-r--r--app/views/addresses/show.html.haml2
-rw-r--r--app/views/automatic_call_distributors/_form_core.html.haml2
-rw-r--r--app/views/automatic_call_distributors/_index_core.html.haml6
-rw-r--r--app/views/automatic_call_distributors/edit.html.haml2
-rw-r--r--app/views/automatic_call_distributors/index.html.haml2
-rw-r--r--app/views/automatic_call_distributors/new.html.haml2
-rw-r--r--app/views/automatic_call_distributors/show.html.haml4
-rw-r--r--app/views/call_forwards/_form_core.html.haml4
-rw-r--r--app/views/call_forwards/_index_core.html.haml6
-rw-r--r--app/views/call_forwards/edit.html.haml2
-rw-r--r--app/views/call_forwards/index.html.haml2
-rw-r--r--app/views/call_forwards/new.html.haml2
-rw-r--r--app/views/call_forwards/show.html.haml2
-rw-r--r--app/views/call_histories/_index_core.html.haml121
-rw-r--r--app/views/call_histories/_navigation.html.haml23
-rw-r--r--app/views/call_histories/index.html.haml4
-rw-r--r--app/views/call_routes/_form.html.haml7
-rw-r--r--app/views/call_routes/_form_core.html.haml5
-rw-r--r--app/views/call_routes/_index_core.html.haml21
-rw-r--r--app/views/call_routes/edit.html.haml3
-rw-r--r--app/views/call_routes/index.html.haml11
-rw-r--r--app/views/call_routes/new.html.haml3
-rw-r--r--app/views/call_routes/show.html.haml22
-rw-r--r--app/views/calls/_index_core.html.haml6
-rw-r--r--app/views/calls/index.html.haml2
-rw-r--r--app/views/callthroughs/_form_core.html.haml2
-rw-r--r--app/views/callthroughs/_index_core.html.haml10
-rw-r--r--app/views/callthroughs/edit.html.haml2
-rw-r--r--app/views/callthroughs/index.html.haml2
-rw-r--r--app/views/callthroughs/new.html.haml2
-rw-r--r--app/views/callthroughs/show.html.haml4
-rw-r--r--app/views/conference_invitees/_index_core.html.haml6
-rw-r--r--app/views/conference_invitees/edit.html.haml2
-rw-r--r--app/views/conference_invitees/index.html.haml2
-rw-r--r--app/views/conference_invitees/new.html.haml2
-rw-r--r--app/views/conference_invitees/show.html.haml2
-rw-r--r--app/views/conferences/_form_core.html.haml2
-rw-r--r--app/views/conferences/_index_core.html.haml6
-rw-r--r--app/views/conferences/edit.html.haml2
-rw-r--r--app/views/conferences/index.html.haml2
-rw-r--r--app/views/conferences/new.html.haml2
-rw-r--r--app/views/conferences/show.html.haml2
-rw-r--r--app/views/config_polycom/_call_history.xml.haml2
-rw-r--r--app/views/config_polycom/_phone_book.xml.haml2
-rw-r--r--app/views/config_snom/show.xml.haml33
-rw-r--r--app/views/config_snom/state_settings.xml.haml2
-rw-r--r--app/views/fax_accounts/_index_core.html.haml6
-rw-r--r--app/views/fax_accounts/edit.html.haml2
-rw-r--r--app/views/fax_accounts/index.html.haml2
-rw-r--r--app/views/fax_accounts/new.html.haml2
-rw-r--r--app/views/fax_accounts/show.html.haml2
-rw-r--r--app/views/fax_documents/_index_core.html.haml6
-rw-r--r--app/views/fax_documents/edit.html.haml2
-rw-r--r--app/views/fax_documents/index.html.haml2
-rw-r--r--app/views/fax_documents/new.html.haml2
-rw-r--r--app/views/fax_documents/show.html.haml2
-rw-r--r--app/views/freeswitch_voicemail_msgs/_index_core.html.haml6
-rw-r--r--app/views/freeswitch_voicemail_msgs/index.html.haml2
-rw-r--r--app/views/gateway_parameters/_form.html.haml7
-rw-r--r--app/views/gateway_parameters/_form_core.html.haml5
-rw-r--r--app/views/gateway_parameters/_index_core.html.haml13
-rw-r--r--app/views/gateway_parameters/edit.html.haml3
-rw-r--r--app/views/gateway_parameters/index.html.haml6
-rw-r--r--app/views/gateway_parameters/new.html.haml3
-rw-r--r--app/views/gateway_parameters/show.html.haml19
-rw-r--r--app/views/gateway_settings/_form.html.haml7
-rw-r--r--app/views/gateway_settings/_form_core.html.haml4
-rw-r--r--app/views/gateway_settings/_index_core.html.haml13
-rw-r--r--app/views/gateway_settings/edit.html.haml3
-rw-r--r--app/views/gateway_settings/index.html.haml6
-rw-r--r--app/views/gateway_settings/new.html.haml3
-rw-r--r--app/views/gateway_settings/show.html.haml19
-rw-r--r--app/views/gateways/_form.html.haml7
-rw-r--r--app/views/gateways/_form_core.html.haml6
-rw-r--r--app/views/gateways/_index_core.html.haml19
-rw-r--r--app/views/gateways/edit.html.haml3
-rw-r--r--app/views/gateways/index.html.haml6
-rw-r--r--app/views/gateways/new.html.haml3
-rw-r--r--app/views/gateways/show.html.haml35
-rw-r--r--app/views/gemeinschaft_setups/new.de.html.haml4
-rw-r--r--app/views/gemeinschaft_setups/new.html.haml4
-rw-r--r--app/views/gs_cluster_sync_log_entries/_index_core.html.haml6
-rw-r--r--app/views/gs_cluster_sync_log_entries/edit.html.haml2
-rw-r--r--app/views/gs_cluster_sync_log_entries/index.html.haml2
-rw-r--r--app/views/gs_cluster_sync_log_entries/new.html.haml2
-rw-r--r--app/views/gs_cluster_sync_log_entries/show.html.haml2
-rw-r--r--app/views/gs_nodes/_index_core.html.haml6
-rw-r--r--app/views/gs_nodes/edit.html.haml2
-rw-r--r--app/views/gs_nodes/index.html.haml2
-rw-r--r--app/views/gs_nodes/new.html.haml2
-rw-r--r--app/views/gs_nodes/show.html.haml2
-rw-r--r--app/views/gs_parameters/_form.html.haml7
-rw-r--r--app/views/gs_parameters/_form_core.html.haml4
-rw-r--r--app/views/gs_parameters/_index_core.html.haml16
-rw-r--r--app/views/gs_parameters/edit.html.haml15
-rw-r--r--app/views/gs_parameters/index.html.haml15
-rw-r--r--app/views/gs_parameters/show.html.haml20
-rw-r--r--app/views/gui_functions/_index_core.html.haml35
-rw-r--r--app/views/gui_functions/edit.html.haml2
-rw-r--r--app/views/gui_functions/index.html.haml5
-rw-r--r--app/views/gui_functions/new.html.haml2
-rw-r--r--app/views/gui_functions/show.html.haml31
-rw-r--r--app/views/hunt_group_members/_index_core.html.haml6
-rw-r--r--app/views/hunt_group_members/edit.html.haml2
-rw-r--r--app/views/hunt_group_members/index.html.haml2
-rw-r--r--app/views/hunt_group_members/new.html.haml2
-rw-r--r--app/views/hunt_group_members/show.html.haml2
-rw-r--r--app/views/hunt_groups/_form_core.html.haml4
-rw-r--r--app/views/hunt_groups/_index_core.html.haml6
-rw-r--r--app/views/hunt_groups/edit.html.haml2
-rw-r--r--app/views/hunt_groups/index.html.haml2
-rw-r--r--app/views/hunt_groups/new.html.haml2
-rw-r--r--app/views/hunt_groups/show.html.haml2
-rw-r--r--app/views/layouts/_footer.html.haml17
-rw-r--r--app/views/layouts/_navbar.html.haml43
-rw-r--r--app/views/layouts/application.html.haml73
-rw-r--r--app/views/layouts/old-application.html.haml48
-rw-r--r--app/views/layouts/old_navbar.html.haml10
-rw-r--r--app/views/layouts/test.haml (renamed from log/.gitkeep)0
-rw-r--r--app/views/manufacturers/_index_core.html.haml6
-rw-r--r--app/views/manufacturers/edit.html.haml2
-rw-r--r--app/views/manufacturers/index.html.haml2
-rw-r--r--app/views/manufacturers/new.html.haml2
-rw-r--r--app/views/manufacturers/show.html.haml2
-rw-r--r--app/views/page/beginners_intro.de.html.haml4
-rw-r--r--app/views/page/beginners_intro.html.haml4
-rw-r--r--app/views/page/conference.html.haml2
-rw-r--r--app/views/page/index.de.html.haml2
-rw-r--r--app/views/page/index.html.haml2
-rw-r--r--app/views/phone_book_entries/_form_core.html.haml2
-rw-r--r--app/views/phone_book_entries/_index_core.de.html.haml72
-rw-r--r--app/views/phone_book_entries/_index_core.html.haml73
-rw-r--r--app/views/phone_book_entries/edit.html.haml2
-rw-r--r--app/views/phone_book_entries/index.html.haml2
-rw-r--r--app/views/phone_book_entries/new.html.haml2
-rw-r--r--app/views/phone_book_entries/show.html.haml17
-rw-r--r--app/views/phone_book_entries/show.html.haml.examlple2
-rw-r--r--app/views/phone_books/_index_core.html.haml18
-rw-r--r--app/views/phone_books/edit.html.haml2
-rw-r--r--app/views/phone_books/index.html.haml2
-rw-r--r--app/views/phone_books/new.html.haml2
-rw-r--r--app/views/phone_books/show.html.haml2
-rw-r--r--app/views/phone_models/_index_core.html.haml6
-rw-r--r--app/views/phone_models/edit.html.haml2
-rw-r--r--app/views/phone_models/index.html.haml2
-rw-r--r--app/views/phone_models/new.html.haml2
-rw-r--r--app/views/phone_models/show.html.haml2
-rw-r--r--app/views/phone_number_ranges/_index_core.html.haml6
-rw-r--r--app/views/phone_number_ranges/edit.html.haml2
-rw-r--r--app/views/phone_number_ranges/index.html.haml2
-rw-r--r--app/views/phone_number_ranges/new.html.haml2
-rw-r--r--app/views/phone_number_ranges/show.html.haml2
-rw-r--r--app/views/phone_numbers/_form_core.html.haml6
-rw-r--r--app/views/phone_numbers/_index_core.html.haml7
-rw-r--r--app/views/phone_numbers/edit.html.haml2
-rw-r--r--app/views/phone_numbers/index.html.haml2
-rw-r--r--app/views/phone_numbers/new.html.haml2
-rw-r--r--app/views/phone_numbers/show.html.haml2
-rw-r--r--app/views/phone_sip_accounts/_index_core.html.haml8
-rw-r--r--app/views/phone_sip_accounts/index.html.haml2
-rw-r--r--app/views/phone_sip_accounts/new.html.haml2
-rw-r--r--app/views/phone_sip_accounts/show.html.haml2
-rw-r--r--app/views/phones/_form_core.html.haml4
-rw-r--r--app/views/phones/_index_core.html.haml6
-rw-r--r--app/views/phones/edit.html.haml2
-rw-r--r--app/views/phones/index.html.haml2
-rw-r--r--app/views/phones/new.html.haml2
-rw-r--r--app/views/phones/show.html.haml16
-rw-r--r--app/views/ringtones/_index_core.html.haml6
-rw-r--r--app/views/ringtones/edit.html.haml2
-rw-r--r--app/views/ringtones/index.html.haml2
-rw-r--r--app/views/ringtones/new.html.haml2
-rw-r--r--app/views/ringtones/show.html.haml2
-rw-r--r--app/views/route_elements/_form.html.haml7
-rw-r--r--app/views/route_elements/_form_core.html.haml7
-rw-r--r--app/views/route_elements/_index_core.html.haml19
-rw-r--r--app/views/route_elements/edit.html.haml3
-rw-r--r--app/views/route_elements/index.html.haml6
-rw-r--r--app/views/route_elements/new.html.haml3
-rw-r--r--app/views/route_elements/show.html.haml22
-rw-r--r--app/views/sessions/new.html.haml2
-rw-r--r--app/views/shared/_create_link.html.haml14
-rw-r--r--app/views/shared/_flash.html.haml19
-rw-r--r--app/views/shared/_index_view_edit_destroy_part.html.haml59
-rw-r--r--app/views/shared/_show_edit_destroy_part.html.haml20
-rw-r--r--app/views/shared/_system_message.html.haml10
-rw-r--r--app/views/sip_accounts/_form_core.html.haml5
-rw-r--r--app/views/sip_accounts/_index_core.html.haml14
-rw-r--r--app/views/sip_accounts/edit.html.haml2
-rw-r--r--app/views/sip_accounts/index.html.haml2
-rw-r--r--app/views/sip_accounts/new.html.haml2
-rw-r--r--app/views/sip_accounts/show.html.haml2
-rw-r--r--app/views/sip_domains/_index_core.html.haml6
-rw-r--r--app/views/sip_domains/edit.html.haml2
-rw-r--r--app/views/sip_domains/index.html.haml2
-rw-r--r--app/views/sip_domains/new.html.haml2
-rw-r--r--app/views/sip_domains/show.html.haml2
-rw-r--r--app/views/softkeys/_index_core.html.haml6
-rw-r--r--app/views/softkeys/edit.html.haml2
-rw-r--r--app/views/softkeys/index.html.haml2
-rw-r--r--app/views/softkeys/new.html.haml2
-rw-r--r--app/views/softkeys/show.html.haml2
-rw-r--r--app/views/system_messages/_index_core.html.haml6
-rw-r--r--app/views/system_messages/index.html.haml2
-rw-r--r--app/views/system_messages/new.html.haml2
-rw-r--r--app/views/system_messages/show.html.haml2
-rw-r--r--app/views/tenants/_admin_area.de.html.haml118
-rw-r--r--app/views/tenants/_admin_area.html.haml126
-rw-r--r--app/views/tenants/_call_routes.html.haml8
-rw-r--r--app/views/tenants/_form.html.haml6
-rw-r--r--app/views/tenants/_gateways.html.haml8
-rw-r--r--app/views/tenants/_gs_parameter_table.html.haml24
-rw-r--r--app/views/tenants/_index_core.html.haml6
-rw-r--r--app/views/tenants/_sip_accounts_and_phones.html.haml68
-rw-r--r--app/views/tenants/_table_of_functions.html.haml53
-rw-r--r--app/views/tenants/_table_of_phone_books.html.haml8
-rw-r--r--app/views/tenants/_user_groups_table.html.haml4
-rw-r--r--app/views/tenants/_users_table.html.haml7
-rw-r--r--app/views/tenants/edit.html.haml2
-rw-r--r--app/views/tenants/index.html.haml2
-rw-r--r--app/views/tenants/new.html.haml2
-rw-r--r--app/views/tenants/show.html.haml9
-rw-r--r--app/views/trigger/fax.html.erb2
-rw-r--r--app/views/trigger/voicemail.html.erb4
-rw-r--r--app/views/user_group_memberships/_index_core.html.haml6
-rw-r--r--app/views/user_group_memberships/edit.html.haml2
-rw-r--r--app/views/user_group_memberships/index.html.haml2
-rw-r--r--app/views/user_group_memberships/new.html.haml2
-rw-r--r--app/views/user_group_memberships/show.html.haml2
-rw-r--r--app/views/user_groups/_index_core.html.haml46
-rw-r--r--app/views/user_groups/edit.html.haml2
-rw-r--r--app/views/user_groups/index.html.haml2
-rw-r--r--app/views/user_groups/new.html.haml2
-rw-r--r--app/views/user_groups/show.html.haml2
-rw-r--r--app/views/users/_conferences.html.haml7
-rw-r--r--app/views/users/_fax_accounts.html.haml7
-rw-r--r--app/views/users/_form_core.html.haml2
-rw-r--r--app/views/users/_index_core.html.haml46
-rw-r--r--app/views/users/_listing.html.haml6
-rw-r--r--app/views/users/_phone_books.html.haml7
-rw-r--r--app/views/users/_phones.html.haml7
-rw-r--r--app/views/users/_sip_accounts.html.haml7
-rw-r--r--app/views/users/_tenants.html.haml5
-rw-r--r--app/views/users/_user_groups.html.haml7
-rw-r--r--app/views/users/edit.html.haml2
-rw-r--r--app/views/users/index.html.haml2
-rw-r--r--app/views/users/new.html.haml2
-rw-r--r--app/views/users/show.html.haml136
-rw-r--r--app/views/voicemail_messages/_index_core.html.haml7
-rw-r--r--app/views/voicemail_messages/index.html.haml4
-rw-r--r--app/views/voicemail_settings/edit.html.haml2
-rw-r--r--app/views/voicemail_settings/show.html.haml2
-rw-r--r--app/views/whitelists/_index_core.html.haml6
-rw-r--r--app/views/whitelists/edit.html.haml2
-rw-r--r--app/views/whitelists/index.html.haml2
-rw-r--r--app/views/whitelists/new.html.haml2
-rw-r--r--app/views/whitelists/show.html.haml2
-rw-r--r--config/application.rb15
-rw-r--r--config/database.yml36
-rw-r--r--config/environments/development.rb5
-rw-r--r--config/environments/production.rb6
-rw-r--r--config/hirb.yml9
-rw-r--r--config/initializers/gemeinschaft_parameters.rb81
-rw-r--r--config/initializers/secret_token.rb2
-rw-r--r--config/initializers/simple_form.rb173
-rw-r--r--config/initializers/update_gs_version_number.rb16
-rw-r--r--config/locales/simple_form.en.yml2
-rw-r--r--config/locales/views/call_routes/de.yml60
-rw-r--r--config/locales/views/call_routes/en.yml60
-rw-r--r--config/locales/views/gateway_parameters/de.yml60
-rw-r--r--config/locales/views/gateway_parameters/en.yml60
-rw-r--r--config/locales/views/gateway_settings/de.yml60
-rw-r--r--config/locales/views/gateway_settings/en.yml60
-rw-r--r--config/locales/views/gateways/de.yml61
-rw-r--r--config/locales/views/gateways/en.yml61
-rw-r--r--config/locales/views/gemeinschaft_setups/de.yml3
-rw-r--r--config/locales/views/gemeinschaft_setups/en.yml3
-rw-r--r--config/locales/views/gs_parameters/de.yml63
-rw-r--r--config/locales/views/gs_parameters/en.yml64
-rw-r--r--config/locales/views/phone_numbers/de.yml3
-rw-r--r--config/locales/views/phone_numbers/en.yml1
-rw-r--r--config/locales/views/route_elements/de.yml75
-rw-r--r--config/locales/views/route_elements/en.yml75
-rw-r--r--config/locales/views/users/de.yml34
-rw-r--r--config/routes.rb33
-rw-r--r--config/unicorn.rb34
-rw-r--r--db/migrate/20121230110747_snom_meetingpoint.rb2
-rw-r--r--db/migrate/20130105120126_create_gs_parameters.rb16
-rw-r--r--db/migrate/20130105120353_populate_gs_parameter_with_defaults.rb104
-rw-r--r--db/migrate/20130107222128_set_provisioning_set_http_user.rb13
-rw-r--r--db/migrate/20130109074326_add_entity_to_gs_parameter.rb6
-rw-r--r--db/migrate/20130109090000_populate_gs_parameter_with_dialplan_defaults.rb121
-rw-r--r--db/migrate/20130109182800_change_gs_parameter_odbc_defaults.rb11
-rw-r--r--db/migrate/20130110085600_set_switch_parameters.rb21
-rw-r--r--db/migrate/20130110113500_set_conference_parameters.rb33
-rw-r--r--db/migrate/20130110133500_set_voicemail_parameters.rb45
-rw-r--r--db/migrate/20130110205056_add_number_of_shown_items_to_gs_parameter.rb9
-rw-r--r--db/migrate/20130111111747_add_secret_token_to_gs_parameter.rb10
-rw-r--r--db/migrate/20130112073300_set_dialplan_variables.rb11
-rw-r--r--db/migrate/20130112074800_remove_ringback_dialplan_parameter.rb9
-rw-r--r--db/migrate/20130112103337_set_new_value_for_provisioning_key_length.rb9
-rw-r--r--db/migrate/20130113072126_create_gateways.rb16
-rw-r--r--db/migrate/20130113073323_create_gateway_settings.rb16
-rw-r--r--db/migrate/20130113090705_create_gateway_parameters.rb16
-rw-r--r--db/migrate/20130116133243_create_call_routes.rb16
-rw-r--r--db/migrate/20130116133433_create_route_elements.rb19
-rw-r--r--db/migrate/20130116145500_set_routing_variables.rb12
-rw-r--r--db/migrate/20130116213312_change_user_name_prefix.rb5
-rw-r--r--db/migrate/20130117142600_change_action_prerouting_table.rb13
-rw-r--r--db/migrate/20130117191840_change_column_name_in_call_route.rb7
-rw-r--r--db/migrate/20130121123742_add_default_area_code_to_gemeinschaft_setup.rb5
-rw-r--r--db/migrate/20130122121100_add_gemeinschaft_buildname_to_gs_parameter.rb9
-rw-r--r--db/schema.rb71
-rw-r--r--db/to-dos/20120119160732_emergency_numbers_germany.rb4
-rwxr-xr-xinstall.sh214
-rw-r--r--lib/activerecord_extensions.rb6
-rw-r--r--lib/bootstrap_breadcrumbs_builder.rb32
-rw-r--r--lib/generators/nifty/authentication/templates/views/haml/edit.html.haml2
-rw-r--r--lib/generators/nifty/authentication/templates/views/haml/login.html.haml2
-rw-r--r--lib/generators/nifty/authentication/templates/views/haml/signup.html.haml2
-rw-r--r--lib/generators/nifty/scaffold/templates/views/haml/_index_core.html.haml6
-rw-r--r--lib/generators/nifty/scaffold/templates/views/haml/edit.html.haml2
-rw-r--r--lib/generators/nifty/scaffold/templates/views/haml/index.html.haml2
-rw-r--r--lib/generators/nifty/scaffold/templates/views/haml/new.html.haml2
-rw-r--r--lib/generators/nifty/scaffold/templates/views/haml/show.html.haml2
-rw-r--r--lib/tasks/cvs_user_import.rake26
-rw-r--r--lib/tasks/fax.rake2
-rw-r--r--lib/tasks/gs_cluster.rake8
-rw-r--r--lib/tasks/heater.rake17
-rw-r--r--lib/tasks/send_fax_notifications.rake2
-rw-r--r--lib/templates/erb/scaffold/_form.html.erb4
-rw-r--r--misc/TODO-Liste.txt0
-rw-r--r--misc/etc/cron.d/logout_phones3
-rw-r--r--misc/etc/ssl/amooma/server.pem36
-rw-r--r--misc/etc/ssl/amooma/server_cert.pem22
-rw-r--r--misc/etc/ssl/amooma/server_key.pem16
-rw-r--r--misc/example/apache-gs5.conf24
-rw-r--r--misc/example/nginx73
-rw-r--r--misc/example/xml-interface.txt25
-rw-r--r--misc/freeswitch/conf/freeswitch.xml106
-rw-r--r--misc/freeswitch/scripts/acd_wait.lua2
-rw-r--r--misc/freeswitch/scripts/common/call_forwarding.lua2
-rw-r--r--misc/freeswitch/scripts/common/call_history.lua2
-rw-r--r--misc/freeswitch/scripts/common/conference.lua6
-rw-r--r--misc/freeswitch/scripts/common/configuration_file.lua2
-rw-r--r--misc/freeswitch/scripts/common/configuration_table.lua46
-rw-r--r--misc/freeswitch/scripts/common/database.lua123
-rw-r--r--misc/freeswitch/scripts/common/fapi.lua2
-rw-r--r--misc/freeswitch/scripts/common/gateway.lua168
-rw-r--r--misc/freeswitch/scripts/common/ipcalc.lua2
-rw-r--r--misc/freeswitch/scripts/common/log.lua2
-rw-r--r--misc/freeswitch/scripts/common/phone_number.lua2
-rw-r--r--misc/freeswitch/scripts/common/routing_tables.lua66
-rw-r--r--misc/freeswitch/scripts/common/sip_account.lua2
-rw-r--r--misc/freeswitch/scripts/common/str.lua24
-rw-r--r--misc/freeswitch/scripts/common/sync_log.lua2
-rw-r--r--misc/freeswitch/scripts/configuration.lua399
-rw-r--r--misc/freeswitch/scripts/configuration/freeswitch_xml.lua307
-rw-r--r--misc/freeswitch/scripts/configuration/simple_xml.lua50
-rw-r--r--misc/freeswitch/scripts/configuration/sip.lua8
-rw-r--r--misc/freeswitch/scripts/dialplan/acd.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/cdr.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/dialplan.lua228
-rw-r--r--misc/freeswitch/scripts/dialplan/fax.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/functions.lua74
-rw-r--r--misc/freeswitch/scripts/dialplan/geo_number.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/hunt_group.lua39
-rw-r--r--misc/freeswitch/scripts/dialplan/phone_book.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/presence.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/route.lua265
-rw-r--r--misc/freeswitch/scripts/dialplan/router.lua187
-rw-r--r--misc/freeswitch/scripts/dialplan/session.lua6
-rw-r--r--misc/freeswitch/scripts/dialplan/sip_call.lua18
-rw-r--r--misc/freeswitch/scripts/dialplan/tenant.lua2
-rw-r--r--misc/freeswitch/scripts/dialplan/user.lua4
-rw-r--r--misc/freeswitch/scripts/dialplan/voicemail.lua4
-rw-r--r--misc/freeswitch/scripts/dialplan_default.lua51
-rw-r--r--misc/freeswitch/scripts/event/call_history_save.lua2
-rw-r--r--misc/freeswitch/scripts/event/cdr_save.lua2
-rw-r--r--misc/freeswitch/scripts/event/event.lua10
-rw-r--r--misc/freeswitch/scripts/event/perimeter.lua5
-rw-r--r--misc/freeswitch/scripts/event_manager.lua5
-rw-r--r--misc/freeswitch/scripts/fax_daemon.lua2
-rw-r--r--misc/freeswitch/scripts/ini/conferences.ini27
-rw-r--r--misc/freeswitch/scripts/ini/database.ini11
-rw-r--r--misc/freeswitch/scripts/ini/dialplan.ini14
-rw-r--r--misc/freeswitch/scripts/ini/events.ini8
-rw-r--r--misc/freeswitch/scripts/ini/gateways.ini.example23
-rw-r--r--misc/freeswitch/scripts/ini/perimeter.ini9
-rw-r--r--misc/freeswitch/scripts/ini/routes.ini77
-rw-r--r--misc/freeswitch/scripts/ini/sip_accounts.ini10
-rw-r--r--misc/freeswitch/scripts/ini/sofia.ini55
-rw-r--r--misc/freeswitch/scripts/phones/phone.lua2
-rw-r--r--misc/freeswitch/scripts/phones/siemens.lua2
-rw-r--r--misc/freeswitch/scripts/phones/snom.lua2
-rw-r--r--misc/freeswitch/scripts/send_fax.lua50
-rw-r--r--misc/mon_ami/asterisk.py2
-rw-r--r--misc/mon_ami/freeswitch.py2
-rw-r--r--misc/mon_ami/helper.py2
-rw-r--r--misc/mon_ami/log.py2
-rwxr-xr-xmisc/mon_ami/mon-ami58
-rwxr-xr-xmisc/mon_ami/mon_ami2
-rw-r--r--misc/mon_ami/mon_ami_handler.py2
-rw-r--r--misc/mon_ami/mon_ami_main.py2
-rw-r--r--misc/mon_ami/mon_ami_server.py2
-rw-r--r--misc/mon_ami/tcp_server.py2
-rw-r--r--misc/nginx/nginx.conf81
-rwxr-xr-xscript/fax_new2
-rwxr-xr-xscript/fax_new.sh4
-rwxr-xr-xscript/logout_phones.sh4
-rwxr-xr-xscript/voicemail_new.sh4
-rw-r--r--test/factories/area_codes.rb10
-rw-r--r--test/factories/call_forwards.rb28
-rw-r--r--test/factories/conference_invitees.rb12
-rw-r--r--test/factories/conferences.rb12
-rw-r--r--test/factories/countries.rb12
-rw-r--r--test/factories/gemeinschaft_setups.rb12
-rw-r--r--test/factories/languages.rb8
-rw-r--r--test/factories/manufacturers.rb8
-rw-r--r--test/factories/ouis.rb8
-rw-r--r--test/factories/phone_book_entries.rb10
-rw-r--r--test/factories/phone_books.rb8
-rw-r--r--test/factories/phone_models.rb8
-rw-r--r--test/factories/phone_number_ranges.rb8
-rw-r--r--test/factories/phone_numbers.rb10
-rw-r--r--test/factories/phones.rb22
-rw-r--r--test/factories/sip_accounts.rb26
-rw-r--r--test/factories/sip_domains.rb8
-rw-r--r--test/factories/tenant_memberships.rb8
-rw-r--r--test/factories/tenants.rb11
-rw-r--r--test/factories/user_group_memberships.rb22
-rw-r--r--test/factories/user_groups.rb8
-rw-r--r--test/factories/users.rb18
-rw-r--r--test/functional/call_forwards_controller_test.rb12
-rw-r--r--test/functional/call_routes_controller_test.rb49
-rw-r--r--test/functional/conference_invitees_controller_test.rb2
-rw-r--r--test/functional/conferences_controller_test.rb2
-rw-r--r--test/functional/gateway_parameters_controller_test.rb49
-rw-r--r--test/functional/gateway_settings_controller_test.rb49
-rw-r--r--test/functional/gateways_controller_test.rb49
-rw-r--r--test/functional/gemeinschaft_setups_controller_test.rb4
-rw-r--r--test/functional/gs_parameters_controller_test.rb49
-rw-r--r--test/functional/manufacturers_controller_test.rb8
-rw-r--r--test/functional/page_controller_test.rb8
-rw-r--r--test/functional/phone_book_entries_controller_test.rb4
-rw-r--r--test/functional/phone_books_controller_test.rb10
-rw-r--r--test/functional/phone_models_controller_test.rb12
-rw-r--r--test/functional/phone_number_ranges_controller_test.rb2
-rw-r--r--test/functional/phone_numbers_controller_test.rb8
-rw-r--r--test/functional/phones_controller_test.rb4
-rw-r--r--test/functional/phones_sip_accounts_controller_test.rb2
-rw-r--r--test/functional/route_elements_controller_test.rb49
-rw-r--r--test/functional/sip_accounts_controller_test.rb8
-rw-r--r--test/functional/sip_domains_controller_test.rb4
-rw-r--r--test/functional/tenants_controller_test.rb4
-rw-r--r--test/functional/trigger_controller_test.rb14
-rw-r--r--test/functional/user_groups_controller_test.rb4
-rw-r--r--test/functional/users_controller_test.rb6
-rw-r--r--test/unit/area_code_test.rb2
-rw-r--r--test/unit/call_forward_test.rb2
-rw-r--r--test/unit/call_route_test.rb7
-rw-r--r--test/unit/callthrough_test.rb10
-rw-r--r--test/unit/conference_invitee_test.rb4
-rw-r--r--test/unit/conference_test.rb22
-rw-r--r--test/unit/country_test.rb2
-rw-r--r--test/unit/gateway_parameter_test.rb7
-rw-r--r--test/unit/gateway_setting_test.rb7
-rw-r--r--test/unit/gateway_test.rb7
-rw-r--r--test/unit/gemeinschaft_setup_test.rb2
-rw-r--r--test/unit/gs_parameter_test.rb7
-rw-r--r--test/unit/helpers/trigger_helper_test.rb4
-rw-r--r--test/unit/language_test.rb2
-rw-r--r--test/unit/manufacturer_test.rb6
-rw-r--r--test/unit/oui_test.rb4
-rw-r--r--test/unit/phone_book_entry_test.rb22
-rw-r--r--test/unit/phone_book_test.rb44
-rw-r--r--test/unit/phone_model_test.rb2
-rw-r--r--test/unit/phone_number_range_test.rb2
-rw-r--r--test/unit/phone_number_test.rb22
-rw-r--r--test/unit/phone_test.rb14
-rw-r--r--test/unit/route_element_test.rb7
-rw-r--r--test/unit/sip_account_test.rb10
-rw-r--r--test/unit/sip_domain_test.rb2
-rw-r--r--test/unit/tenant_membership_test.rb4
-rw-r--r--test/unit/tenant_test.rb12
-rw-r--r--test/unit/user_group_membership_test.rb20
-rw-r--r--test/unit/user_group_test.rb20
-rw-r--r--test/unit/user_test.rb24
650 files changed, 15347 insertions, 9898 deletions
diff --git a/.gitignore b/.gitignore
index 65a18ad..4d70e4a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -83,3 +83,6 @@ tmp/**/*
# Freeswitch
/misc/freeswitch/conf/freeswitch.serial
/misc/freeswitch/scripts/ini/gateway_gateway1.ini
+
+# Cache
+/public/gemeinschaft_setups/*
diff --git a/Gemfile b/Gemfile
index 163c360..2738418 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,18 +1,19 @@
source 'http://rubygems.org'
-gem 'rails', '3.2.2'
-
+gem 'rails', '3.2.11'
gem 'bcrypt-ruby'
-
gem 'sqlite3'
-
gem 'mysql2'
-
-gem 'cancan'
-
+gem 'cancan', '1.6.7'
gem 'state_machine'
-
gem 'acts_as_list'
+gem 'dalli' # memcached
+gem 'inifile'
+
+# Useful Rails 4 stuff
+#
+gem 'strong_parameters'
+gem 'cache_digests'
# Nicer console output:
gem "hirb"
@@ -22,15 +23,10 @@ gem "nokogiri"
# Gems used only for assets and not required
# in production environments by default.
group :assets do
- gem 'sass-rails', '~> 3.2.3'
+ gem 'sass-rails'
gem 'coffee-rails', '~> 3.2.1'
gem 'compass-rails'
-
- # See https://github.com/sstephenson/execjs#readme for more supported runtimes
- gem 'therubyracer'
-
- gem 'uglifier', '>= 1.0.3'
-
+ gem 'uglifier', '>= 1.3.0'
end
gem 'json'
@@ -40,7 +36,8 @@ gem 'jquery-rails'
group :development do
gem 'factory_girl_rails'
gem 'factory_girl'
- gem "rails-erd", "~> 0.4.5"
+ gem 'sextant' # Rails 4 stuff
+ gem 'quiet_assets' # turns off assets logging
end
group :test do
@@ -73,6 +70,11 @@ gem 'breadcrumbs_on_rails'
# UUID Generator https://github.com/assaf/uuid
gem 'uuid'
+# Application server
+gem 'unicorn'
+
+gem 'thin'
+
# Local Variables:
# mode: ruby
# End:
diff --git a/Gemfile.lock b/Gemfile.lock
index f9a6596..79c6339 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,176 +1,194 @@
GEM
remote: http://rubygems.org/
specs:
- actionmailer (3.2.2)
- actionpack (= 3.2.2)
- mail (~> 2.4.0)
- actionpack (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
+ actionmailer (3.2.11)
+ actionpack (= 3.2.11)
+ mail (~> 2.4.4)
+ actionpack (3.2.11)
+ activemodel (= 3.2.11)
+ activesupport (= 3.2.11)
builder (~> 3.0.0)
erubis (~> 2.7.0)
- journey (~> 1.0.1)
+ journey (~> 1.0.4)
rack (~> 1.4.0)
- rack-cache (~> 1.1)
+ rack-cache (~> 1.2)
rack-test (~> 0.6.1)
- sprockets (~> 2.1.2)
- activemodel (3.2.2)
- activesupport (= 3.2.2)
+ sprockets (~> 2.2.1)
+ activemodel (3.2.11)
+ activesupport (= 3.2.11)
builder (~> 3.0.0)
- activerecord (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
+ activerecord (3.2.11)
+ activemodel (= 3.2.11)
+ activesupport (= 3.2.11)
arel (~> 3.0.2)
tzinfo (~> 0.3.29)
- activeresource (3.2.2)
- activemodel (= 3.2.2)
- activesupport (= 3.2.2)
- activesupport (3.2.2)
+ activeresource (3.2.11)
+ activemodel (= 3.2.11)
+ activesupport (= 3.2.11)
+ activesupport (3.2.11)
i18n (~> 0.6)
multi_json (~> 1.0)
- acts_as_list (0.1.5)
- addressable (2.2.7)
+ acts_as_list (0.1.9)
+ addressable (2.3.2)
arel (3.0.2)
bcrypt-ruby (3.0.1)
- breadcrumbs_on_rails (2.2.0)
- builder (3.0.0)
+ breadcrumbs_on_rails (2.3.0)
+ builder (3.0.4)
+ cache_digests (0.2.0)
+ actionpack (>= 3.2)
cancan (1.6.7)
- carrierwave (0.5.8)
- activesupport (~> 3.0)
- chunky_png (1.2.5)
+ carrierwave (0.8.0)
+ activemodel (>= 3.2.0)
+ activesupport (>= 3.2.0)
+ chunky_png (1.2.7)
coffee-rails (3.2.2)
coffee-script (>= 2.2.0)
railties (~> 3.2.0)
coffee-script (2.2.0)
coffee-script-source
execjs
- coffee-script-source (1.2.0)
- compass (0.12.rc.1)
+ coffee-script-source (1.4.0)
+ compass (0.12.2)
chunky_png (~> 1.2)
fssm (>= 0.2.7)
sass (~> 3.1)
- compass-rails (1.0.0.rc.3)
- compass (~> 0.12.rc.0)
+ compass-rails (1.0.3)
+ compass (>= 0.12.2, < 0.14)
cookiejar (0.3.0)
- delayed_job (3.0.1)
+ daemons (1.1.9)
+ dalli (2.6.0)
+ delayed_job (3.0.4)
activesupport (~> 3.0)
- delayed_job_active_record (0.3.2)
- activerecord (> 2.1.0)
- delayed_job (~> 3.0.0)
- em-http-request (1.0.1)
+ delayed_job_active_record (0.3.3)
+ activerecord (>= 2.1.0, < 4)
+ delayed_job (~> 3.0)
+ em-http-request (1.0.3)
addressable (>= 2.2.3)
cookiejar
em-socksify
eventmachine (>= 1.0.0.beta.4)
http_parser.rb (>= 0.5.3)
- em-socksify (0.1.0)
- eventmachine
+ em-socksify (0.2.1)
+ eventmachine (>= 1.0.0.beta.4)
erubis (2.7.0)
- eventmachine (1.0.0.beta.4)
- execjs (1.3.0)
+ eventmachine (1.0.0)
+ execjs (1.4.0)
multi_json (~> 1.0)
- factory_girl (2.6.1)
- activesupport (>= 2.3.9)
- factory_girl_rails (1.7.0)
- factory_girl (~> 2.6.0)
+ factory_girl (4.1.0)
+ activesupport (>= 3.0.0)
+ factory_girl_rails (4.1.0)
+ factory_girl (~> 4.1.0)
railties (>= 3.0.0)
- faye (0.8.0)
+ faye (0.8.8)
cookiejar (>= 0.3.0)
em-http-request (>= 0.3.0)
eventmachine (>= 0.12.0)
faye-websocket (>= 0.4.0)
rack (>= 1.0.0)
yajl-ruby (>= 1.0.0)
- faye-websocket (0.4.1)
+ faye-websocket (0.4.6)
eventmachine (>= 0.12.0)
- fssm (0.2.8.1)
+ fssm (0.2.9)
haml (3.1.7)
hike (1.2.1)
- hirb (0.6.1)
+ hirb (0.7.0)
http_accept_language (1.0.2)
http_parser.rb (0.5.3)
- i18n (0.6.0)
- journey (1.0.3)
- jquery-rails (2.0.1)
- railties (>= 3.2.0, < 5.0)
- thor (~> 0.14)
- json (1.6.5)
- libv8 (3.3.10.4)
+ i18n (0.6.1)
+ inifile (2.0.2)
+ journey (1.0.4)
+ jquery-rails (2.1.4)
+ railties (>= 3.0, < 5.0)
+ thor (>= 0.14, < 2.0)
+ json (1.7.6)
+ kgio (2.7.4)
macaddr (1.6.1)
systemu (~> 2.5.0)
- mail (2.4.3)
+ mail (2.4.4)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
- mime-types (1.17.2)
+ mime-types (1.19)
mini_magick (3.4)
subexec (~> 0.2.1)
- multi_json (1.1.0)
+ multi_json (1.5.0)
mysql2 (0.3.11)
- nokogiri (1.5.5)
+ nokogiri (1.5.6)
polyglot (0.3.3)
- private_pub (1.0.1)
+ private_pub (1.0.3)
faye
- rack (1.4.1)
+ quiet_assets (1.0.1)
+ railties (~> 3.1)
+ rack (1.4.4)
rack-cache (1.2)
rack (>= 0.4)
rack-ssl (1.3.2)
rack
- rack-test (0.6.1)
+ rack-test (0.6.2)
rack (>= 1.0)
- rails (3.2.2)
- actionmailer (= 3.2.2)
- actionpack (= 3.2.2)
- activerecord (= 3.2.2)
- activeresource (= 3.2.2)
- activesupport (= 3.2.2)
+ rails (3.2.11)
+ actionmailer (= 3.2.11)
+ actionpack (= 3.2.11)
+ activerecord (= 3.2.11)
+ activeresource (= 3.2.11)
+ activesupport (= 3.2.11)
bundler (~> 1.0)
- railties (= 3.2.2)
- rails-erd (0.4.5)
- activerecord (~> 3.0)
- activesupport (~> 3.0)
- ruby-graphviz (~> 0.9.18)
- railties (3.2.2)
- actionpack (= 3.2.2)
- activesupport (= 3.2.2)
+ railties (= 3.2.11)
+ railties (3.2.11)
+ actionpack (= 3.2.11)
+ activesupport (= 3.2.11)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
- thor (~> 0.14.6)
- rake (0.9.2.2)
+ thor (>= 0.14.6, < 2.0)
+ raindrops (0.10.0)
+ rake (10.0.3)
rdoc (3.12)
json (~> 1.4)
- ruby-graphviz (0.9.21)
- sass (3.1.15)
- sass-rails (3.2.4)
+ sass (3.2.5)
+ sass-rails (3.2.6)
railties (~> 3.2.0)
sass (>= 3.1.10)
tilt (~> 1.3)
+ sextant (0.2.3)
+ activesupport (>= 3.2)
+ rails (>= 3.2)
simple_form (2.0.1)
actionpack (~> 3.0)
activemodel (~> 3.0)
- sprockets (2.1.2)
+ sprockets (2.2.2)
hike (~> 1.2)
+ multi_json (~> 1.0)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
- sqlite3 (1.3.5)
+ sqlite3 (1.3.7)
state_machine (1.1.2)
- subexec (0.2.1)
- systemu (2.5.1)
- therubyracer (0.9.10)
- libv8 (~> 3.3.10)
- thor (0.14.6)
+ strong_parameters (0.1.6)
+ actionpack (~> 3.0)
+ activemodel (~> 3.0)
+ railties (~> 3.0)
+ subexec (0.2.2)
+ systemu (2.5.2)
+ thin (1.5.0)
+ daemons (>= 1.0.9)
+ eventmachine (>= 0.12.6)
+ rack (>= 1.0.0)
+ thor (0.16.0)
tilt (1.3.3)
- treetop (1.4.10)
+ treetop (1.4.12)
polyglot
polyglot (>= 0.3.1)
- tzinfo (0.3.32)
- uglifier (1.2.3)
+ tzinfo (0.3.35)
+ uglifier (1.3.0)
execjs (>= 0.3.0)
- multi_json (>= 1.0.2)
- uuid (2.3.5)
+ multi_json (~> 1.0, >= 1.0.2)
+ unicorn (4.5.0)
+ kgio (~> 2.6)
+ rack
+ raindrops (~> 0.7)
+ uuid (2.3.6)
macaddr (~> 1.0)
- will_paginate (3.0.3)
+ will_paginate (3.0.4)
yajl-ruby (1.1.0)
PLATFORMS
@@ -180,10 +198,12 @@ DEPENDENCIES
acts_as_list
bcrypt-ruby
breadcrumbs_on_rails
- cancan
+ cache_digests
+ cancan (= 1.6.7)
carrierwave
coffee-rails (~> 3.2.1)
compass-rails
+ dalli
delayed_job
delayed_job_active_record
factory_girl
@@ -191,19 +211,23 @@ DEPENDENCIES
haml
hirb
http_accept_language
+ inifile
jquery-rails
json
mini_magick
mysql2
nokogiri
private_pub
- rails (= 3.2.2)
- rails-erd (~> 0.4.5)
- sass-rails (~> 3.2.3)
+ quiet_assets
+ rails (= 3.2.11)
+ sass-rails
+ sextant
simple_form (= 2.0.1)
sqlite3
state_machine
- therubyracer
- uglifier (>= 1.0.3)
+ strong_parameters
+ thin
+ uglifier (>= 1.3.0)
+ unicorn
uuid
will_paginate
diff --git a/app/assets/images/amooma-logo.png b/app/assets/images/amooma-logo.png
deleted file mode 100644
index 11096ff..0000000
--- a/app/assets/images/amooma-logo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/bg-body.png b/app/assets/images/bg-body.png
deleted file mode 100644
index 777eff6..0000000
--- a/app/assets/images/bg-body.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/gradients/light-to-dark-blue-x63.png b/app/assets/images/gradients/light-to-dark-blue-x63.png
deleted file mode 100644
index 7eb020f..0000000
--- a/app/assets/images/gradients/light-to-dark-blue-x63.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/gradients/white-gray-x29-reverse.png b/app/assets/images/gradients/white-gray-x29-reverse.png
deleted file mode 100644
index 7b7e879..0000000
--- a/app/assets/images/gradients/white-gray-x29-reverse.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/gradients/white-gray-x29.png b/app/assets/images/gradients/white-gray-x29.png
deleted file mode 100644
index a1671d0..0000000
--- a/app/assets/images/gradients/white-gray-x29.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/gradients/white-texture-x63.png b/app/assets/images/gradients/white-texture-x63.png
deleted file mode 100644
index 1576e8f..0000000
--- a/app/assets/images/gradients/white-texture-x63.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icons/glyphicons-halflings-white.png b/app/assets/images/icons/glyphicons-halflings-white.png
new file mode 100644
index 0000000..3bf6484
--- /dev/null
+++ b/app/assets/images/icons/glyphicons-halflings-white.png
Binary files differ
diff --git a/app/assets/images/icons/glyphicons-halflings.png b/app/assets/images/icons/glyphicons-halflings.png
new file mode 100644
index 0000000..a996999
--- /dev/null
+++ b/app/assets/images/icons/glyphicons-halflings.png
Binary files differ
diff --git a/app/assets/images/logo.png b/app/assets/images/logo.png
deleted file mode 100644
index e4432b8..0000000
--- a/app/assets/images/logo.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom300.png b/app/assets/images/phones/snom/Visio_snom300.png
new file mode 100644
index 0000000..42e7a87
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom300.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom320.png b/app/assets/images/phones/snom/Visio_snom320.png
new file mode 100644
index 0000000..9e91a57
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom320.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom360.png b/app/assets/images/phones/snom/Visio_snom360.png
new file mode 100644
index 0000000..aeb9115
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom360.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom370.png b/app/assets/images/phones/snom/Visio_snom370.png
new file mode 100644
index 0000000..e900b34
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom370.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom820.png b/app/assets/images/phones/snom/Visio_snom820.png
new file mode 100644
index 0000000..3ec75c7
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom820.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom821.png b/app/assets/images/phones/snom/Visio_snom821.png
new file mode 100644
index 0000000..3ec75c7
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom821.png
Binary files differ
diff --git a/app/assets/images/phones/snom/Visio_snom870.png b/app/assets/images/phones/snom/Visio_snom870.png
new file mode 100644
index 0000000..1550591
--- /dev/null
+++ b/app/assets/images/phones/snom/Visio_snom870.png
Binary files differ
diff --git a/app/assets/images/stubs/user-36x.jpg b/app/assets/images/stubs/user-36x.jpg
deleted file mode 100644
index 8a391a0..0000000
--- a/app/assets/images/stubs/user-36x.jpg
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/user.png b/app/assets/images/user.png
deleted file mode 100644
index c0e33c7..0000000
--- a/app/assets/images/user.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 1762043..9097d83 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -1,14 +1,15 @@
-// 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
+// This is a manifest file that'll be compiled into application.js, which will include all the files
+// listed below.
+//
+// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
+// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
+//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// the compiled file.
//
+// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
+// GO AFTER THE REQUIRES BELOW.
+//
//= require jquery
//= require jquery_ujs
-//= require core
-//= require vendor/modernizr-2.0.6.min.js
-//= require vendor/jquery.condom.js
-//= require vendor/jquery.survival-kit
-//= require phones
-//= require softkeys
+//= require_tree .
diff --git a/app/assets/javascripts/bootstrap.js b/app/assets/javascripts/bootstrap.js
new file mode 100644
index 0000000..c753bd6
--- /dev/null
+++ b/app/assets/javascripts/bootstrap.js
@@ -0,0 +1,2025 @@
+/* ===================================================
+ * bootstrap-transition.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#transitions
+ * ===================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* CSS TRANSITION SUPPORT (http://www.modernizr.com/)
+ * ======================================================= */
+
+ $(function () {
+
+ $.support.transition = (function () {
+
+ var transitionEnd = (function () {
+
+ var el = document.createElement('bootstrap')
+ , transEndEventNames = {
+ 'WebkitTransition' : 'webkitTransitionEnd'
+ , 'MozTransition' : 'transitionend'
+ , 'OTransition' : 'oTransitionEnd otransitionend'
+ , 'transition' : 'transitionend'
+ }
+ , name
+
+ for (name in transEndEventNames){
+ if (el.style[name] !== undefined) {
+ return transEndEventNames[name]
+ }
+ }
+
+ }())
+
+ return transitionEnd && {
+ end: transitionEnd
+ }
+
+ })()
+
+ })
+
+}(window.jQuery);/* ==========================================================
+ * bootstrap-alert.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#alerts
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* ALERT CLASS DEFINITION
+ * ====================== */
+
+ var dismiss = '[data-dismiss="alert"]'
+ , Alert = function (el) {
+ $(el).on('click', dismiss, this.close)
+ }
+
+ Alert.prototype.close = function (e) {
+ var $this = $(this)
+ , selector = $this.attr('data-target')
+ , $parent
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = $(selector)
+
+ e && e.preventDefault()
+
+ $parent.length || ($parent = $this.hasClass('alert') ? $this : $this.parent())
+
+ $parent.trigger(e = $.Event('close'))
+
+ if (e.isDefaultPrevented()) return
+
+ $parent.removeClass('in')
+
+ function removeElement() {
+ $parent
+ .trigger('closed')
+ .remove()
+ }
+
+ $.support.transition && $parent.hasClass('fade') ?
+ $parent.on($.support.transition.end, removeElement) :
+ removeElement()
+ }
+
+
+ /* ALERT PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.alert = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('alert')
+ if (!data) $this.data('alert', (data = new Alert(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.alert.Constructor = Alert
+
+
+ /* ALERT DATA-API
+ * ============== */
+
+ $(document).on('click.alert.data-api', dismiss, Alert.prototype.close)
+
+}(window.jQuery);/* ============================================================
+ * bootstrap-button.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#buttons
+ * ============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* BUTTON PUBLIC CLASS DEFINITION
+ * ============================== */
+
+ var Button = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.button.defaults, options)
+ }
+
+ Button.prototype.setState = function (state) {
+ var d = 'disabled'
+ , $el = this.$element
+ , data = $el.data()
+ , val = $el.is('input') ? 'val' : 'html'
+
+ state = state + 'Text'
+ data.resetText || $el.data('resetText', $el[val]())
+
+ $el[val](data[state] || this.options[state])
+
+ // push to event loop to allow forms to submit
+ setTimeout(function () {
+ state == 'loadingText' ?
+ $el.addClass(d).attr(d, d) :
+ $el.removeClass(d).removeAttr(d)
+ }, 0)
+ }
+
+ Button.prototype.toggle = function () {
+ var $parent = this.$element.closest('[data-toggle="buttons-radio"]')
+
+ $parent && $parent
+ .find('.active')
+ .removeClass('active')
+
+ this.$element.toggleClass('active')
+ }
+
+
+ /* BUTTON PLUGIN DEFINITION
+ * ======================== */
+
+ $.fn.button = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('button')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('button', (data = new Button(this, options)))
+ if (option == 'toggle') data.toggle()
+ else if (option) data.setState(option)
+ })
+ }
+
+ $.fn.button.defaults = {
+ loadingText: 'loading...'
+ }
+
+ $.fn.button.Constructor = Button
+
+
+ /* BUTTON DATA-API
+ * =============== */
+
+ $(document).on('click.button.data-api', '[data-toggle^=button]', function (e) {
+ var $btn = $(e.target)
+ if (!$btn.hasClass('btn')) $btn = $btn.closest('.btn')
+ $btn.button('toggle')
+ })
+
+}(window.jQuery);/* ==========================================================
+ * bootstrap-carousel.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#carousel
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* CAROUSEL CLASS DEFINITION
+ * ========================= */
+
+ var Carousel = function (element, options) {
+ this.$element = $(element)
+ this.options = options
+ this.options.slide && this.slide(this.options.slide)
+ this.options.pause == 'hover' && this.$element
+ .on('mouseenter', $.proxy(this.pause, this))
+ .on('mouseleave', $.proxy(this.cycle, this))
+ }
+
+ Carousel.prototype = {
+
+ cycle: function (e) {
+ if (!e) this.paused = false
+ this.options.interval
+ && !this.paused
+ && (this.interval = setInterval($.proxy(this.next, this), this.options.interval))
+ return this
+ }
+
+ , to: function (pos) {
+ var $active = this.$element.find('.item.active')
+ , children = $active.parent().children()
+ , activePos = children.index($active)
+ , that = this
+
+ if (pos > (children.length - 1) || pos < 0) return
+
+ if (this.sliding) {
+ return this.$element.one('slid', function () {
+ that.to(pos)
+ })
+ }
+
+ if (activePos == pos) {
+ return this.pause().cycle()
+ }
+
+ return this.slide(pos > activePos ? 'next' : 'prev', $(children[pos]))
+ }
+
+ , pause: function (e) {
+ if (!e) this.paused = true
+ if (this.$element.find('.next, .prev').length && $.support.transition.end) {
+ this.$element.trigger($.support.transition.end)
+ this.cycle()
+ }
+ clearInterval(this.interval)
+ this.interval = null
+ return this
+ }
+
+ , next: function () {
+ if (this.sliding) return
+ return this.slide('next')
+ }
+
+ , prev: function () {
+ if (this.sliding) return
+ return this.slide('prev')
+ }
+
+ , slide: function (type, next) {
+ var $active = this.$element.find('.item.active')
+ , $next = next || $active[type]()
+ , isCycling = this.interval
+ , direction = type == 'next' ? 'left' : 'right'
+ , fallback = type == 'next' ? 'first' : 'last'
+ , that = this
+ , e
+
+ this.sliding = true
+
+ isCycling && this.pause()
+
+ $next = $next.length ? $next : this.$element.find('.item')[fallback]()
+
+ e = $.Event('slide', {
+ relatedTarget: $next[0]
+ })
+
+ if ($next.hasClass('active')) return
+
+ if ($.support.transition && this.$element.hasClass('slide')) {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $next.addClass(type)
+ $next[0].offsetWidth // force reflow
+ $active.addClass(direction)
+ $next.addClass(direction)
+ this.$element.one($.support.transition.end, function () {
+ $next.removeClass([type, direction].join(' ')).addClass('active')
+ $active.removeClass(['active', direction].join(' '))
+ that.sliding = false
+ setTimeout(function () { that.$element.trigger('slid') }, 0)
+ })
+ } else {
+ this.$element.trigger(e)
+ if (e.isDefaultPrevented()) return
+ $active.removeClass('active')
+ $next.addClass('active')
+ this.sliding = false
+ this.$element.trigger('slid')
+ }
+
+ isCycling && this.cycle()
+
+ return this
+ }
+
+ }
+
+
+ /* CAROUSEL PLUGIN DEFINITION
+ * ========================== */
+
+ $.fn.carousel = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('carousel')
+ , options = $.extend({}, $.fn.carousel.defaults, typeof option == 'object' && option)
+ , action = typeof option == 'string' ? option : options.slide
+ if (!data) $this.data('carousel', (data = new Carousel(this, options)))
+ if (typeof option == 'number') data.to(option)
+ else if (action) data[action]()
+ else if (options.interval) data.cycle()
+ })
+ }
+
+ $.fn.carousel.defaults = {
+ interval: 5000
+ , pause: 'hover'
+ }
+
+ $.fn.carousel.Constructor = Carousel
+
+
+ /* CAROUSEL DATA-API
+ * ================= */
+
+ $(document).on('click.carousel.data-api', '[data-slide]', function (e) {
+ var $this = $(this), href
+ , $target = $($this.attr('data-target') || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ , options = $.extend({}, $target.data(), $this.data())
+ $target.carousel(options)
+ e.preventDefault()
+ })
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-collapse.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#collapse
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* COLLAPSE PUBLIC CLASS DEFINITION
+ * ================================ */
+
+ var Collapse = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.collapse.defaults, options)
+
+ if (this.options.parent) {
+ this.$parent = $(this.options.parent)
+ }
+
+ this.options.toggle && this.toggle()
+ }
+
+ Collapse.prototype = {
+
+ constructor: Collapse
+
+ , dimension: function () {
+ var hasWidth = this.$element.hasClass('width')
+ return hasWidth ? 'width' : 'height'
+ }
+
+ , show: function () {
+ var dimension
+ , scroll
+ , actives
+ , hasData
+
+ if (this.transitioning) return
+
+ dimension = this.dimension()
+ scroll = $.camelCase(['scroll', dimension].join('-'))
+ actives = this.$parent && this.$parent.find('> .accordion-group > .in')
+
+ if (actives && actives.length) {
+ hasData = actives.data('collapse')
+ if (hasData && hasData.transitioning) return
+ actives.collapse('hide')
+ hasData || actives.data('collapse', null)
+ }
+
+ this.$element[dimension](0)
+ this.transition('addClass', $.Event('show'), 'shown')
+ $.support.transition && this.$element[dimension](this.$element[0][scroll])
+ }
+
+ , hide: function () {
+ var dimension
+ if (this.transitioning) return
+ dimension = this.dimension()
+ this.reset(this.$element[dimension]())
+ this.transition('removeClass', $.Event('hide'), 'hidden')
+ this.$element[dimension](0)
+ }
+
+ , reset: function (size) {
+ var dimension = this.dimension()
+
+ this.$element
+ .removeClass('collapse')
+ [dimension](size || 'auto')
+ [0].offsetWidth
+
+ this.$element[size !== null ? 'addClass' : 'removeClass']('collapse')
+
+ return this
+ }
+
+ , transition: function (method, startEvent, completeEvent) {
+ var that = this
+ , complete = function () {
+ if (startEvent.type == 'show') that.reset()
+ that.transitioning = 0
+ that.$element.trigger(completeEvent)
+ }
+
+ this.$element.trigger(startEvent)
+
+ if (startEvent.isDefaultPrevented()) return
+
+ this.transitioning = 1
+
+ this.$element[method]('in')
+
+ $.support.transition && this.$element.hasClass('collapse') ?
+ this.$element.one($.support.transition.end, complete) :
+ complete()
+ }
+
+ , toggle: function () {
+ this[this.$element.hasClass('in') ? 'hide' : 'show']()
+ }
+
+ }
+
+
+ /* COLLAPSIBLE PLUGIN DEFINITION
+ * ============================== */
+
+ $.fn.collapse = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('collapse')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('collapse', (data = new Collapse(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.collapse.defaults = {
+ toggle: true
+ }
+
+ $.fn.collapse.Constructor = Collapse
+
+
+ /* COLLAPSIBLE DATA-API
+ * ==================== */
+
+ $(document).on('click.collapse.data-api', '[data-toggle=collapse]', function (e) {
+ var $this = $(this), href
+ , target = $this.attr('data-target')
+ || e.preventDefault()
+ || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
+ , option = $(target).data('collapse') ? 'toggle' : $this.data()
+ $this[$(target).hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
+ $(target).collapse(option)
+ })
+
+}(window.jQuery);/* ============================================================
+ * bootstrap-dropdown.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#dropdowns
+ * ============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* DROPDOWN CLASS DEFINITION
+ * ========================= */
+
+ var toggle = '[data-toggle=dropdown]'
+ , Dropdown = function (element) {
+ var $el = $(element).on('click.dropdown.data-api', this.toggle)
+ $('html').on('click.dropdown.data-api', function () {
+ $el.parent().removeClass('open')
+ })
+ }
+
+ Dropdown.prototype = {
+
+ constructor: Dropdown
+
+ , toggle: function (e) {
+ var $this = $(this)
+ , $parent
+ , isActive
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ clearMenus()
+
+ if (!isActive) {
+ $parent.toggleClass('open')
+ $this.focus()
+ }
+
+ return false
+ }
+
+ , keydown: function (e) {
+ var $this
+ , $items
+ , $active
+ , $parent
+ , isActive
+ , index
+
+ if (!/(38|40|27)/.test(e.keyCode)) return
+
+ $this = $(this)
+
+ e.preventDefault()
+ e.stopPropagation()
+
+ if ($this.is('.disabled, :disabled')) return
+
+ $parent = getParent($this)
+
+ isActive = $parent.hasClass('open')
+
+ if (!isActive || (isActive && e.keyCode == 27)) return $this.click()
+
+ $items = $('[role=menu] li:not(.divider) a', $parent)
+
+ if (!$items.length) return
+
+ index = $items.index($items.filter(':focus'))
+
+ if (e.keyCode == 38 && index > 0) index-- // up
+ if (e.keyCode == 40 && index < $items.length - 1) index++ // down
+ if (!~index) index = 0
+
+ $items
+ .eq(index)
+ .focus()
+ }
+
+ }
+
+ function clearMenus() {
+ $(toggle).each(function () {
+ getParent($(this)).removeClass('open')
+ })
+ }
+
+ function getParent($this) {
+ var selector = $this.attr('data-target')
+ , $parent
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && /#/.test(selector) && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ $parent = $(selector)
+ $parent.length || ($parent = $this.parent())
+
+ return $parent
+ }
+
+
+ /* DROPDOWN PLUGIN DEFINITION
+ * ========================== */
+
+ $.fn.dropdown = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('dropdown')
+ if (!data) $this.data('dropdown', (data = new Dropdown(this)))
+ if (typeof option == 'string') data[option].call($this)
+ })
+ }
+
+ $.fn.dropdown.Constructor = Dropdown
+
+
+ /* APPLY TO STANDARD DROPDOWN ELEMENTS
+ * =================================== */
+
+ $(document)
+ .on('click.dropdown.data-api touchstart.dropdown.data-api', clearMenus)
+ .on('click.dropdown touchstart.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
+ .on('click.dropdown.data-api touchstart.dropdown.data-api' , toggle, Dropdown.prototype.toggle)
+ .on('keydown.dropdown.data-api touchstart.dropdown.data-api', toggle + ', [role=menu]' , Dropdown.prototype.keydown)
+
+}(window.jQuery);/* =========================================================
+ * bootstrap-modal.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#modals
+ * =========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================= */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* MODAL CLASS DEFINITION
+ * ====================== */
+
+ var Modal = function (element, options) {
+ this.options = options
+ this.$element = $(element)
+ .delegate('[data-dismiss="modal"]', 'click.dismiss.modal', $.proxy(this.hide, this))
+ this.options.remote && this.$element.find('.modal-body').load(this.options.remote)
+ }
+
+ Modal.prototype = {
+
+ constructor: Modal
+
+ , toggle: function () {
+ return this[!this.isShown ? 'show' : 'hide']()
+ }
+
+ , show: function () {
+ var that = this
+ , e = $.Event('show')
+
+ this.$element.trigger(e)
+
+ if (this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = true
+
+ this.escape()
+
+ this.backdrop(function () {
+ var transition = $.support.transition && that.$element.hasClass('fade')
+
+ if (!that.$element.parent().length) {
+ that.$element.appendTo(document.body) //don't move modals dom position
+ }
+
+ that.$element
+ .show()
+
+ if (transition) {
+ that.$element[0].offsetWidth // force reflow
+ }
+
+ that.$element
+ .addClass('in')
+ .attr('aria-hidden', false)
+
+ that.enforceFocus()
+
+ transition ?
+ that.$element.one($.support.transition.end, function () { that.$element.focus().trigger('shown') }) :
+ that.$element.focus().trigger('shown')
+
+ })
+ }
+
+ , hide: function (e) {
+ e && e.preventDefault()
+
+ var that = this
+
+ e = $.Event('hide')
+
+ this.$element.trigger(e)
+
+ if (!this.isShown || e.isDefaultPrevented()) return
+
+ this.isShown = false
+
+ this.escape()
+
+ $(document).off('focusin.modal')
+
+ this.$element
+ .removeClass('in')
+ .attr('aria-hidden', true)
+
+ $.support.transition && this.$element.hasClass('fade') ?
+ this.hideWithTransition() :
+ this.hideModal()
+ }
+
+ , enforceFocus: function () {
+ var that = this
+ $(document).on('focusin.modal', function (e) {
+ if (that.$element[0] !== e.target && !that.$element.has(e.target).length) {
+ that.$element.focus()
+ }
+ })
+ }
+
+ , escape: function () {
+ var that = this
+ if (this.isShown && this.options.keyboard) {
+ this.$element.on('keyup.dismiss.modal', function ( e ) {
+ e.which == 27 && that.hide()
+ })
+ } else if (!this.isShown) {
+ this.$element.off('keyup.dismiss.modal')
+ }
+ }
+
+ , hideWithTransition: function () {
+ var that = this
+ , timeout = setTimeout(function () {
+ that.$element.off($.support.transition.end)
+ that.hideModal()
+ }, 500)
+
+ this.$element.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ that.hideModal()
+ })
+ }
+
+ , hideModal: function (that) {
+ this.$element
+ .hide()
+ .trigger('hidden')
+
+ this.backdrop()
+ }
+
+ , removeBackdrop: function () {
+ this.$backdrop.remove()
+ this.$backdrop = null
+ }
+
+ , backdrop: function (callback) {
+ var that = this
+ , animate = this.$element.hasClass('fade') ? 'fade' : ''
+
+ if (this.isShown && this.options.backdrop) {
+ var doAnimate = $.support.transition && animate
+
+ this.$backdrop = $('<div class="modal-backdrop ' + animate + '" />')
+ .appendTo(document.body)
+
+ this.$backdrop.click(
+ this.options.backdrop == 'static' ?
+ $.proxy(this.$element[0].focus, this.$element[0])
+ : $.proxy(this.hide, this)
+ )
+
+ if (doAnimate) this.$backdrop[0].offsetWidth // force reflow
+
+ this.$backdrop.addClass('in')
+
+ doAnimate ?
+ this.$backdrop.one($.support.transition.end, callback) :
+ callback()
+
+ } else if (!this.isShown && this.$backdrop) {
+ this.$backdrop.removeClass('in')
+
+ $.support.transition && this.$element.hasClass('fade')?
+ this.$backdrop.one($.support.transition.end, $.proxy(this.removeBackdrop, this)) :
+ this.removeBackdrop()
+
+ } else if (callback) {
+ callback()
+ }
+ }
+ }
+
+
+ /* MODAL PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.modal = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('modal')
+ , options = $.extend({}, $.fn.modal.defaults, $this.data(), typeof option == 'object' && option)
+ if (!data) $this.data('modal', (data = new Modal(this, options)))
+ if (typeof option == 'string') data[option]()
+ else if (options.show) data.show()
+ })
+ }
+
+ $.fn.modal.defaults = {
+ backdrop: true
+ , keyboard: true
+ , show: true
+ }
+
+ $.fn.modal.Constructor = Modal
+
+
+ /* MODAL DATA-API
+ * ============== */
+
+ $(document).on('click.modal.data-api', '[data-toggle="modal"]', function (e) {
+ var $this = $(this)
+ , href = $this.attr('href')
+ , $target = $($this.attr('data-target') || (href && href.replace(/.*(?=#[^\s]+$)/, ''))) //strip for ie7
+ , option = $target.data('modal') ? 'toggle' : $.extend({ remote:!/#/.test(href) && href }, $target.data(), $this.data())
+
+ e.preventDefault()
+
+ $target
+ .modal(option)
+ .one('hide', function () {
+ $this.focus()
+ })
+ })
+
+}(window.jQuery);
+/* ===========================================================
+ * bootstrap-tooltip.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#tooltips
+ * Inspired by the original jQuery.tipsy by Jason Frame
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TOOLTIP PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Tooltip = function (element, options) {
+ this.init('tooltip', element, options)
+ }
+
+ Tooltip.prototype = {
+
+ constructor: Tooltip
+
+ , init: function (type, element, options) {
+ var eventIn
+ , eventOut
+
+ this.type = type
+ this.$element = $(element)
+ this.options = this.getOptions(options)
+ this.enabled = true
+
+ if (this.options.trigger == 'click') {
+ this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
+ } else if (this.options.trigger != 'manual') {
+ eventIn = this.options.trigger == 'hover' ? 'mouseenter' : 'focus'
+ eventOut = this.options.trigger == 'hover' ? 'mouseleave' : 'blur'
+ this.$element.on(eventIn + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
+ this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
+ }
+
+ this.options.selector ?
+ (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
+ this.fixTitle()
+ }
+
+ , getOptions: function (options) {
+ options = $.extend({}, $.fn[this.type].defaults, options, this.$element.data())
+
+ if (options.delay && typeof options.delay == 'number') {
+ options.delay = {
+ show: options.delay
+ , hide: options.delay
+ }
+ }
+
+ return options
+ }
+
+ , enter: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (!self.options.delay || !self.options.delay.show) return self.show()
+
+ clearTimeout(this.timeout)
+ self.hoverState = 'in'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'in') self.show()
+ }, self.options.delay.show)
+ }
+
+ , leave: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+
+ if (this.timeout) clearTimeout(this.timeout)
+ if (!self.options.delay || !self.options.delay.hide) return self.hide()
+
+ self.hoverState = 'out'
+ this.timeout = setTimeout(function() {
+ if (self.hoverState == 'out') self.hide()
+ }, self.options.delay.hide)
+ }
+
+ , show: function () {
+ var $tip
+ , inside
+ , pos
+ , actualWidth
+ , actualHeight
+ , placement
+ , tp
+
+ if (this.hasContent() && this.enabled) {
+ $tip = this.tip()
+ this.setContent()
+
+ if (this.options.animation) {
+ $tip.addClass('fade')
+ }
+
+ placement = typeof this.options.placement == 'function' ?
+ this.options.placement.call(this, $tip[0], this.$element[0]) :
+ this.options.placement
+
+ inside = /in/.test(placement)
+
+ $tip
+ .detach()
+ .css({ top: 0, left: 0, display: 'block' })
+ .insertAfter(this.$element)
+
+ pos = this.getPosition(inside)
+
+ actualWidth = $tip[0].offsetWidth
+ actualHeight = $tip[0].offsetHeight
+
+ switch (inside ? placement.split(' ')[1] : placement) {
+ case 'bottom':
+ tp = {top: pos.top + pos.height, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'top':
+ tp = {top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2}
+ break
+ case 'left':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth}
+ break
+ case 'right':
+ tp = {top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width}
+ break
+ }
+
+ $tip
+ .offset(tp)
+ .addClass(placement)
+ .addClass('in')
+ }
+ }
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+
+ $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
+ $tip.removeClass('fade in top bottom left right')
+ }
+
+ , hide: function () {
+ var that = this
+ , $tip = this.tip()
+
+ $tip.removeClass('in')
+
+ function removeWithAnimation() {
+ var timeout = setTimeout(function () {
+ $tip.off($.support.transition.end).detach()
+ }, 500)
+
+ $tip.one($.support.transition.end, function () {
+ clearTimeout(timeout)
+ $tip.detach()
+ })
+ }
+
+ $.support.transition && this.$tip.hasClass('fade') ?
+ removeWithAnimation() :
+ $tip.detach()
+
+ return this
+ }
+
+ , fixTitle: function () {
+ var $e = this.$element
+ if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
+ $e.attr('data-original-title', $e.attr('title') || '').removeAttr('title')
+ }
+ }
+
+ , hasContent: function () {
+ return this.getTitle()
+ }
+
+ , getPosition: function (inside) {
+ return $.extend({}, (inside ? {top: 0, left: 0} : this.$element.offset()), {
+ width: this.$element[0].offsetWidth
+ , height: this.$element[0].offsetHeight
+ })
+ }
+
+ , getTitle: function () {
+ var title
+ , $e = this.$element
+ , o = this.options
+
+ title = $e.attr('data-original-title')
+ || (typeof o.title == 'function' ? o.title.call($e[0]) : o.title)
+
+ return title
+ }
+
+ , tip: function () {
+ return this.$tip = this.$tip || $(this.options.template)
+ }
+
+ , validate: function () {
+ if (!this.$element[0].parentNode) {
+ this.hide()
+ this.$element = null
+ this.options = null
+ }
+ }
+
+ , enable: function () {
+ this.enabled = true
+ }
+
+ , disable: function () {
+ this.enabled = false
+ }
+
+ , toggleEnabled: function () {
+ this.enabled = !this.enabled
+ }
+
+ , toggle: function (e) {
+ var self = $(e.currentTarget)[this.type](this._options).data(this.type)
+ self[self.tip().hasClass('in') ? 'hide' : 'show']()
+ }
+
+ , destroy: function () {
+ this.hide().$element.off('.' + this.type).removeData(this.type)
+ }
+
+ }
+
+
+ /* TOOLTIP PLUGIN DEFINITION
+ * ========================= */
+
+ $.fn.tooltip = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tooltip')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('tooltip', (data = new Tooltip(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tooltip.Constructor = Tooltip
+
+ $.fn.tooltip.defaults = {
+ animation: true
+ , placement: 'top'
+ , selector: false
+ , template: '<div class="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>'
+ , trigger: 'hover'
+ , title: ''
+ , delay: 0
+ , html: false
+ }
+
+}(window.jQuery);/* ===========================================================
+ * bootstrap-popover.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#popovers
+ * ===========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * =========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* POPOVER PUBLIC CLASS DEFINITION
+ * =============================== */
+
+ var Popover = function (element, options) {
+ this.init('popover', element, options)
+ }
+
+
+ /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js
+ ========================================== */
+
+ Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, {
+
+ constructor: Popover
+
+ , setContent: function () {
+ var $tip = this.tip()
+ , title = this.getTitle()
+ , content = this.getContent()
+
+ $tip.find('.popover-title')[this.options.html ? 'html' : 'text'](title)
+ $tip.find('.popover-content > *')[this.options.html ? 'html' : 'text'](content)
+
+ $tip.removeClass('fade top bottom left right in')
+ }
+
+ , hasContent: function () {
+ return this.getTitle() || this.getContent()
+ }
+
+ , getContent: function () {
+ var content
+ , $e = this.$element
+ , o = this.options
+
+ content = $e.attr('data-content')
+ || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content)
+
+ return content
+ }
+
+ , tip: function () {
+ if (!this.$tip) {
+ this.$tip = $(this.options.template)
+ }
+ return this.$tip
+ }
+
+ , destroy: function () {
+ this.hide().$element.off('.' + this.type).removeData(this.type)
+ }
+
+ })
+
+
+ /* POPOVER PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.popover = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('popover')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('popover', (data = new Popover(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.popover.Constructor = Popover
+
+ $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, {
+ placement: 'right'
+ , trigger: 'click'
+ , content: ''
+ , template: '<div class="popover"><div class="arrow"></div><div class="popover-inner"><h3 class="popover-title"></h3><div class="popover-content"><p></p></div></div></div>'
+ })
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-scrollspy.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#scrollspy
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* SCROLLSPY CLASS DEFINITION
+ * ========================== */
+
+ function ScrollSpy(element, options) {
+ var process = $.proxy(this.process, this)
+ , $element = $(element).is('body') ? $(window) : $(element)
+ , href
+ this.options = $.extend({}, $.fn.scrollspy.defaults, options)
+ this.$scrollElement = $element.on('scroll.scroll-spy.data-api', process)
+ this.selector = (this.options.target
+ || ((href = $(element).attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '')) //strip for ie7
+ || '') + ' .nav li > a'
+ this.$body = $('body')
+ this.refresh()
+ this.process()
+ }
+
+ ScrollSpy.prototype = {
+
+ constructor: ScrollSpy
+
+ , refresh: function () {
+ var self = this
+ , $targets
+
+ this.offsets = $([])
+ this.targets = $([])
+
+ $targets = this.$body
+ .find(this.selector)
+ .map(function () {
+ var $el = $(this)
+ , href = $el.data('target') || $el.attr('href')
+ , $href = /^#\w/.test(href) && $(href)
+ return ( $href
+ && $href.length
+ && [[ $href.position().top, href ]] ) || null
+ })
+ .sort(function (a, b) { return a[0] - b[0] })
+ .each(function () {
+ self.offsets.push(this[0])
+ self.targets.push(this[1])
+ })
+ }
+
+ , process: function () {
+ var scrollTop = this.$scrollElement.scrollTop() + this.options.offset
+ , scrollHeight = this.$scrollElement[0].scrollHeight || this.$body[0].scrollHeight
+ , maxScroll = scrollHeight - this.$scrollElement.height()
+ , offsets = this.offsets
+ , targets = this.targets
+ , activeTarget = this.activeTarget
+ , i
+
+ if (scrollTop >= maxScroll) {
+ return activeTarget != (i = targets.last()[0])
+ && this.activate ( i )
+ }
+
+ for (i = offsets.length; i--;) {
+ activeTarget != targets[i]
+ && scrollTop >= offsets[i]
+ && (!offsets[i + 1] || scrollTop <= offsets[i + 1])
+ && this.activate( targets[i] )
+ }
+ }
+
+ , activate: function (target) {
+ var active
+ , selector
+
+ this.activeTarget = target
+
+ $(this.selector)
+ .parent('.active')
+ .removeClass('active')
+
+ selector = this.selector
+ + '[data-target="' + target + '"],'
+ + this.selector + '[href="' + target + '"]'
+
+ active = $(selector)
+ .parent('li')
+ .addClass('active')
+
+ if (active.parent('.dropdown-menu').length) {
+ active = active.closest('li.dropdown').addClass('active')
+ }
+
+ active.trigger('activate')
+ }
+
+ }
+
+
+ /* SCROLLSPY PLUGIN DEFINITION
+ * =========================== */
+
+ $.fn.scrollspy = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('scrollspy')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('scrollspy', (data = new ScrollSpy(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.scrollspy.Constructor = ScrollSpy
+
+ $.fn.scrollspy.defaults = {
+ offset: 10
+ }
+
+
+ /* SCROLLSPY DATA-API
+ * ================== */
+
+ $(window).on('load', function () {
+ $('[data-spy="scroll"]').each(function () {
+ var $spy = $(this)
+ $spy.scrollspy($spy.data())
+ })
+ })
+
+}(window.jQuery);/* ========================================================
+ * bootstrap-tab.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#tabs
+ * ========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ======================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* TAB CLASS DEFINITION
+ * ==================== */
+
+ var Tab = function (element) {
+ this.element = $(element)
+ }
+
+ Tab.prototype = {
+
+ constructor: Tab
+
+ , show: function () {
+ var $this = this.element
+ , $ul = $this.closest('ul:not(.dropdown-menu)')
+ , selector = $this.attr('data-target')
+ , previous
+ , $target
+ , e
+
+ if (!selector) {
+ selector = $this.attr('href')
+ selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
+ }
+
+ if ( $this.parent('li').hasClass('active') ) return
+
+ previous = $ul.find('.active:last a')[0]
+
+ e = $.Event('show', {
+ relatedTarget: previous
+ })
+
+ $this.trigger(e)
+
+ if (e.isDefaultPrevented()) return
+
+ $target = $(selector)
+
+ this.activate($this.parent('li'), $ul)
+ this.activate($target, $target.parent(), function () {
+ $this.trigger({
+ type: 'shown'
+ , relatedTarget: previous
+ })
+ })
+ }
+
+ , activate: function ( element, container, callback) {
+ var $active = container.find('> .active')
+ , transition = callback
+ && $.support.transition
+ && $active.hasClass('fade')
+
+ function next() {
+ $active
+ .removeClass('active')
+ .find('> .dropdown-menu > .active')
+ .removeClass('active')
+
+ element.addClass('active')
+
+ if (transition) {
+ element[0].offsetWidth // reflow for transition
+ element.addClass('in')
+ } else {
+ element.removeClass('fade')
+ }
+
+ if ( element.parent('.dropdown-menu') ) {
+ element.closest('li.dropdown').addClass('active')
+ }
+
+ callback && callback()
+ }
+
+ transition ?
+ $active.one($.support.transition.end, next) :
+ next()
+
+ $active.removeClass('in')
+ }
+ }
+
+
+ /* TAB PLUGIN DEFINITION
+ * ===================== */
+
+ $.fn.tab = function ( option ) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('tab')
+ if (!data) $this.data('tab', (data = new Tab(this)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.tab.Constructor = Tab
+
+
+ /* TAB DATA-API
+ * ============ */
+
+ $(document).on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
+ e.preventDefault()
+ $(this).tab('show')
+ })
+
+}(window.jQuery);/* =============================================================
+ * bootstrap-typeahead.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#typeahead
+ * =============================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ============================================================ */
+
+
+!function($){
+
+ "use strict"; // jshint ;_;
+
+
+ /* TYPEAHEAD PUBLIC CLASS DEFINITION
+ * ================================= */
+
+ var Typeahead = function (element, options) {
+ this.$element = $(element)
+ this.options = $.extend({}, $.fn.typeahead.defaults, options)
+ this.matcher = this.options.matcher || this.matcher
+ this.sorter = this.options.sorter || this.sorter
+ this.highlighter = this.options.highlighter || this.highlighter
+ this.updater = this.options.updater || this.updater
+ this.$menu = $(this.options.menu).appendTo('body')
+ this.source = this.options.source
+ this.shown = false
+ this.listen()
+ }
+
+ Typeahead.prototype = {
+
+ constructor: Typeahead
+
+ , select: function () {
+ var val = this.$menu.find('.active').attr('data-value')
+ this.$element
+ .val(this.updater(val))
+ .change()
+ return this.hide()
+ }
+
+ , updater: function (item) {
+ return item
+ }
+
+ , show: function () {
+ var pos = $.extend({}, this.$element.offset(), {
+ height: this.$element[0].offsetHeight
+ })
+
+ this.$menu.css({
+ top: pos.top + pos.height
+ , left: pos.left
+ })
+
+ this.$menu.show()
+ this.shown = true
+ return this
+ }
+
+ , hide: function () {
+ this.$menu.hide()
+ this.shown = false
+ return this
+ }
+
+ , lookup: function (event) {
+ var items
+
+ this.query = this.$element.val()
+
+ if (!this.query || this.query.length < this.options.minLength) {
+ return this.shown ? this.hide() : this
+ }
+
+ items = $.isFunction(this.source) ? this.source(this.query, $.proxy(this.process, this)) : this.source
+
+ return items ? this.process(items) : this
+ }
+
+ , process: function (items) {
+ var that = this
+
+ items = $.grep(items, function (item) {
+ return that.matcher(item)
+ })
+
+ items = this.sorter(items)
+
+ if (!items.length) {
+ return this.shown ? this.hide() : this
+ }
+
+ return this.render(items.slice(0, this.options.items)).show()
+ }
+
+ , matcher: function (item) {
+ return ~item.toLowerCase().indexOf(this.query.toLowerCase())
+ }
+
+ , sorter: function (items) {
+ var beginswith = []
+ , caseSensitive = []
+ , caseInsensitive = []
+ , item
+
+ while (item = items.shift()) {
+ if (!item.toLowerCase().indexOf(this.query.toLowerCase())) beginswith.push(item)
+ else if (~item.indexOf(this.query)) caseSensitive.push(item)
+ else caseInsensitive.push(item)
+ }
+
+ return beginswith.concat(caseSensitive, caseInsensitive)
+ }
+
+ , highlighter: function (item) {
+ var query = this.query.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, '\\$&')
+ return item.replace(new RegExp('(' + query + ')', 'ig'), function ($1, match) {
+ return '<strong>' + match + '</strong>'
+ })
+ }
+
+ , render: function (items) {
+ var that = this
+
+ items = $(items).map(function (i, item) {
+ i = $(that.options.item).attr('data-value', item)
+ i.find('a').html(that.highlighter(item))
+ return i[0]
+ })
+
+ items.first().addClass('active')
+ this.$menu.html(items)
+ return this
+ }
+
+ , next: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , next = active.next()
+
+ if (!next.length) {
+ next = $(this.$menu.find('li')[0])
+ }
+
+ next.addClass('active')
+ }
+
+ , prev: function (event) {
+ var active = this.$menu.find('.active').removeClass('active')
+ , prev = active.prev()
+
+ if (!prev.length) {
+ prev = this.$menu.find('li').last()
+ }
+
+ prev.addClass('active')
+ }
+
+ , listen: function () {
+ this.$element
+ .on('blur', $.proxy(this.blur, this))
+ .on('keypress', $.proxy(this.keypress, this))
+ .on('keyup', $.proxy(this.keyup, this))
+
+ if (this.eventSupported('keydown')) {
+ this.$element.on('keydown', $.proxy(this.keydown, this))
+ }
+
+ this.$menu
+ .on('click', $.proxy(this.click, this))
+ .on('mouseenter', 'li', $.proxy(this.mouseenter, this))
+ }
+
+ , eventSupported: function(eventName) {
+ var isSupported = eventName in this.$element
+ if (!isSupported) {
+ this.$element.setAttribute(eventName, 'return;')
+ isSupported = typeof this.$element[eventName] === 'function'
+ }
+ return isSupported
+ }
+
+ , move: function (e) {
+ if (!this.shown) return
+
+ switch(e.keyCode) {
+ case 9: // tab
+ case 13: // enter
+ case 27: // escape
+ e.preventDefault()
+ break
+
+ case 38: // up arrow
+ e.preventDefault()
+ this.prev()
+ break
+
+ case 40: // down arrow
+ e.preventDefault()
+ this.next()
+ break
+ }
+
+ e.stopPropagation()
+ }
+
+ , keydown: function (e) {
+ this.suppressKeyPressRepeat = !~$.inArray(e.keyCode, [40,38,9,13,27])
+ this.move(e)
+ }
+
+ , keypress: function (e) {
+ if (this.suppressKeyPressRepeat) return
+ this.move(e)
+ }
+
+ , keyup: function (e) {
+ switch(e.keyCode) {
+ case 40: // down arrow
+ case 38: // up arrow
+ case 16: // shift
+ case 17: // ctrl
+ case 18: // alt
+ break
+
+ case 9: // tab
+ case 13: // enter
+ if (!this.shown) return
+ this.select()
+ break
+
+ case 27: // escape
+ if (!this.shown) return
+ this.hide()
+ break
+
+ default:
+ this.lookup()
+ }
+
+ e.stopPropagation()
+ e.preventDefault()
+ }
+
+ , blur: function (e) {
+ var that = this
+ setTimeout(function () { that.hide() }, 150)
+ }
+
+ , click: function (e) {
+ e.stopPropagation()
+ e.preventDefault()
+ this.select()
+ }
+
+ , mouseenter: function (e) {
+ this.$menu.find('.active').removeClass('active')
+ $(e.currentTarget).addClass('active')
+ }
+
+ }
+
+
+ /* TYPEAHEAD PLUGIN DEFINITION
+ * =========================== */
+
+ $.fn.typeahead = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('typeahead')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('typeahead', (data = new Typeahead(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.typeahead.defaults = {
+ source: []
+ , items: 8
+ , menu: '<ul class="typeahead dropdown-menu"></ul>'
+ , item: '<li><a href="#"></a></li>'
+ , minLength: 1
+ }
+
+ $.fn.typeahead.Constructor = Typeahead
+
+
+ /* TYPEAHEAD DATA-API
+ * ================== */
+
+ $(document).on('focus.typeahead.data-api', '[data-provide="typeahead"]', function (e) {
+ var $this = $(this)
+ if ($this.data('typeahead')) return
+ e.preventDefault()
+ $this.typeahead($this.data())
+ })
+
+}(window.jQuery);
+/* ==========================================================
+ * bootstrap-affix.js v2.2.1
+ * http://twitter.github.com/bootstrap/javascript.html#affix
+ * ==========================================================
+ * Copyright 2012 Twitter, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * ========================================================== */
+
+
+!function ($) {
+
+ "use strict"; // jshint ;_;
+
+
+ /* AFFIX CLASS DEFINITION
+ * ====================== */
+
+ var Affix = function (element, options) {
+ this.options = $.extend({}, $.fn.affix.defaults, options)
+ this.$window = $(window)
+ .on('scroll.affix.data-api', $.proxy(this.checkPosition, this))
+ .on('click.affix.data-api', $.proxy(function () { setTimeout($.proxy(this.checkPosition, this), 1) }, this))
+ this.$element = $(element)
+ this.checkPosition()
+ }
+
+ Affix.prototype.checkPosition = function () {
+ if (!this.$element.is(':visible')) return
+
+ var scrollHeight = $(document).height()
+ , scrollTop = this.$window.scrollTop()
+ , position = this.$element.offset()
+ , offset = this.options.offset
+ , offsetBottom = offset.bottom
+ , offsetTop = offset.top
+ , reset = 'affix affix-top affix-bottom'
+ , affix
+
+ if (typeof offset != 'object') offsetBottom = offsetTop = offset
+ if (typeof offsetTop == 'function') offsetTop = offset.top()
+ if (typeof offsetBottom == 'function') offsetBottom = offset.bottom()
+
+ affix = this.unpin != null && (scrollTop + this.unpin <= position.top) ?
+ false : offsetBottom != null && (position.top + this.$element.height() >= scrollHeight - offsetBottom) ?
+ 'bottom' : offsetTop != null && scrollTop <= offsetTop ?
+ 'top' : false
+
+ if (this.affixed === affix) return
+
+ this.affixed = affix
+ this.unpin = affix == 'bottom' ? position.top - scrollTop : null
+
+ this.$element.removeClass(reset).addClass('affix' + (affix ? '-' + affix : ''))
+ }
+
+
+ /* AFFIX PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.affix = function (option) {
+ return this.each(function () {
+ var $this = $(this)
+ , data = $this.data('affix')
+ , options = typeof option == 'object' && option
+ if (!data) $this.data('affix', (data = new Affix(this, options)))
+ if (typeof option == 'string') data[option]()
+ })
+ }
+
+ $.fn.affix.Constructor = Affix
+
+ $.fn.affix.defaults = {
+ offset: 0
+ }
+
+
+ /* AFFIX DATA-API
+ * ============== */
+
+ $(window).on('load', function () {
+ $('[data-spy="affix"]').each(function () {
+ var $spy = $(this)
+ , data = $spy.data()
+
+ data.offset = data.offset || {}
+
+ data.offsetBottom && (data.offset.bottom = data.offsetBottom)
+ data.offsetTop && (data.offset.top = data.offsetTop)
+
+ $spy.affix(data)
+ })
+ })
+
+
+}(window.jQuery); \ No newline at end of file
diff --git a/app/assets/javascripts/config_siemens.js.coffee b/app/assets/javascripts/config_siemens.js.coffee
deleted file mode 100644
index 7615679..0000000
--- a/app/assets/javascripts/config_siemens.js.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-# 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/core.coffee b/app/assets/javascripts/core.coffee
deleted file mode 100644
index af12aa7..0000000
--- a/app/assets/javascripts/core.coffee
+++ /dev/null
@@ -1,5 +0,0 @@
-$(document).ready ->
- $sk = $.ns('sk')
- $sk('.search-box').searchBox()
- $sk('.simple_form').simpleForms()
- \ No newline at end of file
diff --git a/app/assets/javascripts/phones.js.coffee b/app/assets/javascripts/phones.js.coffee
deleted file mode 100644
index d917d09..0000000
--- a/app/assets/javascripts/phones.js.coffee
+++ /dev/null
@@ -1,3 +0,0 @@
-jQuery ->
- $("#phone_hot_deskable").change ->
- $(".fallback_sip_account_dropdown").show("slow")
diff --git a/app/assets/javascripts/softkeys.js.coffee b/app/assets/javascripts/softkeys.js.coffee
deleted file mode 100644
index 23d5233..0000000
--- a/app/assets/javascripts/softkeys.js.coffee
+++ /dev/null
@@ -1,25 +0,0 @@
-jQuery ->
- function_name = $('#softkey_softkey_function_id :selected').text()
-
- if function_name == call_forwarding_function_name
- $('#softkey_call_forward_id').parent().show()
- $('#softkey_number').parent().hide()
- else
- $('#softkey_call_forward_id').parent().hide()
- if (function_name == hold_function_name || function_name == deactivated_function_name)
- $('#softkey_number').parent().hide()
- else
- $('#softkey_number').parent().show()
-
- $('#softkey_softkey_function_id').change ->
- $('#softkey_label').parent().show()
- function_name = $('#softkey_softkey_function_id :selected').text()
- if function_name == call_forwarding_function_name
- $('#softkey_call_forward_id').parent().show("slow")
- $('#softkey_number').parent().hide("slow")
- else
- $('#softkey_call_forward_id').parent().hide("slow")
- if (function_name == hold_function_name || function_name == deactivated_function_name)
- $('#softkey_number').parent().hide("slow")
- else
- $('#softkey_number').parent().show("slow")
diff --git a/app/assets/javascripts/api/rows.js.coffee b/app/assets/javascripts/trigger.js.coffee
index 7615679..7615679 100644
--- a/app/assets/javascripts/api/rows.js.coffee
+++ b/app/assets/javascripts/trigger.js.coffee
diff --git a/app/assets/javascripts/vendor/autoresize.jquery.js b/app/assets/javascripts/vendor/autoresize.jquery.js
deleted file mode 100644
index 28cec5d..0000000
--- a/app/assets/javascripts/vendor/autoresize.jquery.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * jQuery autoResize (textarea auto-resizer)
- * @copyright James Padolsey http://james.padolsey.com
- * @version 1.04
- */
-
-(function($){
- $.fn.autoResize = function(options) {
- // Just some abstracted details,
- // to make plugin users happy:
- var settings = $.extend({
- onResize : function(){},
- animate : true,
- animateDuration : 150,
- animateCallback : function(){},
- extraSpace : 20,
- limit: 1000
- }, options);
-
- // Only textarea's auto-resize:
- this.filter('textarea').each(function(){
-
- // Get rid of scrollbars and disable WebKit resizing:
- var textarea = $(this).css({resize:'none','overflow-y':'hidden'}),
-
- // Cache original height, for use later:
- origHeight = textarea.height(),
-
- // Need clone of textarea, hidden off screen:
- clone = (function(){
-
- // Properties which may effect space taken up by chracters:
- var props = ['height','width','lineHeight','textDecoration','letterSpacing'],
- propOb = {};
-
- // Create object of styles to apply:
- $.each(props, function(i, prop){
- propOb[prop] = textarea.css(prop);
- });
-
- // Clone the actual textarea removing unique properties
- // and insert before original textarea:
- return textarea.clone().removeAttr('id').removeAttr('name').css({
- position: 'absolute',
- top: 0,
- left: -9999
- }).css(propOb).attr('tabIndex','-1').insertBefore(textarea);
-
- })(),
- lastScrollTop = null,
- updateSize = function() {
-
- // Prepare the clone:
- clone.height(0).val($(this).val()).scrollTop(10000);
-
- // Find the height of text:
- var scrollTop = Math.max(clone.scrollTop(), origHeight) + settings.extraSpace,
- toChange = $(this).add(clone);
-
- // Don't do anything if scrollTip hasen't changed:
- if (lastScrollTop === scrollTop) { return; }
- lastScrollTop = scrollTop;
-
- // Check for limit:
- if ( scrollTop >= settings.limit ) {
- $(this).css('overflow-y','');
- return;
- }
- // Fire off callback:
- settings.onResize.call(this);
-
- // Either animate or directly apply height:
- settings.animate && textarea.css('display') === 'block' ?
- toChange.stop().animate({height:scrollTop}, settings.animateDuration, settings.animateCallback)
- : toChange.height(scrollTop);
- };
-
- // Bind namespaced handlers to appropriate events:
- textarea
- .unbind('.dynSiz')
- .bind('keyup.dynSiz', updateSize)
- .bind('keydown.dynSiz', updateSize)
- .bind('change.dynSiz', updateSize);
-
- });
-
- // Chain:
- return this;
-
- };
-
-
-
-})(jQuery);
diff --git a/app/assets/javascripts/vendor/fancybox/jquery.easing-1.3.pack.js b/app/assets/javascripts/vendor/fancybox/jquery.easing-1.3.pack.js
deleted file mode 100755
index ef74321..0000000
--- a/app/assets/javascripts/vendor/fancybox/jquery.easing-1.3.pack.js
+++ /dev/null
@@ -1,205 +0,0 @@
-/*
- * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
- *
- * Uses the built in easing capabilities added In jQuery 1.1
- * to offer multiple easing options
- *
- * TERMS OF USE - jQuery Easing
- *
- * Open source under the BSD License.
- *
- * Copyright © 2008 George McGinley Smith
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * Neither the name of the author nor the names of contributors may be used to endorse
- * or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
-*/
-
-// t: current time, b: begInnIng value, c: change In value, d: duration
-jQuery.easing['jswing'] = jQuery.easing['swing'];
-
-jQuery.extend( jQuery.easing,
-{
- def: 'easeOutQuad',
- swing: function (x, t, b, c, d) {
- //alert(jQuery.easing.default);
- return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
- },
- easeInQuad: function (x, t, b, c, d) {
- return c*(t/=d)*t + b;
- },
- easeOutQuad: function (x, t, b, c, d) {
- return -c *(t/=d)*(t-2) + b;
- },
- easeInOutQuad: function (x, t, b, c, d) {
- if ((t/=d/2) < 1) return c/2*t*t + b;
- return -c/2 * ((--t)*(t-2) - 1) + b;
- },
- easeInCubic: function (x, t, b, c, d) {
- return c*(t/=d)*t*t + b;
- },
- easeOutCubic: function (x, t, b, c, d) {
- return c*((t=t/d-1)*t*t + 1) + b;
- },
- easeInOutCubic: function (x, t, b, c, d) {
- if ((t/=d/2) < 1) return c/2*t*t*t + b;
- return c/2*((t-=2)*t*t + 2) + b;
- },
- easeInQuart: function (x, t, b, c, d) {
- return c*(t/=d)*t*t*t + b;
- },
- easeOutQuart: function (x, t, b, c, d) {
- return -c * ((t=t/d-1)*t*t*t - 1) + b;
- },
- easeInOutQuart: function (x, t, b, c, d) {
- if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
- return -c/2 * ((t-=2)*t*t*t - 2) + b;
- },
- easeInQuint: function (x, t, b, c, d) {
- return c*(t/=d)*t*t*t*t + b;
- },
- easeOutQuint: function (x, t, b, c, d) {
- return c*((t=t/d-1)*t*t*t*t + 1) + b;
- },
- easeInOutQuint: function (x, t, b, c, d) {
- if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
- return c/2*((t-=2)*t*t*t*t + 2) + b;
- },
- easeInSine: function (x, t, b, c, d) {
- return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
- },
- easeOutSine: function (x, t, b, c, d) {
- return c * Math.sin(t/d * (Math.PI/2)) + b;
- },
- easeInOutSine: function (x, t, b, c, d) {
- return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
- },
- easeInExpo: function (x, t, b, c, d) {
- return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
- },
- easeOutExpo: function (x, t, b, c, d) {
- return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
- },
- easeInOutExpo: function (x, t, b, c, d) {
- if (t==0) return b;
- if (t==d) return b+c;
- if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
- return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
- },
- easeInCirc: function (x, t, b, c, d) {
- return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
- },
- easeOutCirc: function (x, t, b, c, d) {
- return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
- },
- easeInOutCirc: function (x, t, b, c, d) {
- if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
- return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
- },
- easeInElastic: function (x, t, b, c, d) {
- var s=1.70158;var p=0;var a=c;
- if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
- if (a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
- },
- easeOutElastic: function (x, t, b, c, d) {
- var s=1.70158;var p=0;var a=c;
- if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
- if (a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
- },
- easeInOutElastic: function (x, t, b, c, d) {
- var s=1.70158;var p=0;var a=c;
- if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
- if (a < Math.abs(c)) { a=c; var s=p/4; }
- else var s = p/(2*Math.PI) * Math.asin (c/a);
- if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
- return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
- },
- easeInBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- return c*(t/=d)*t*((s+1)*t - s) + b;
- },
- easeOutBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
- },
- easeInOutBack: function (x, t, b, c, d, s) {
- if (s == undefined) s = 1.70158;
- if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
- return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
- },
- easeInBounce: function (x, t, b, c, d) {
- return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
- },
- easeOutBounce: function (x, t, b, c, d) {
- if ((t/=d) < (1/2.75)) {
- return c*(7.5625*t*t) + b;
- } else if (t < (2/2.75)) {
- return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
- } else if (t < (2.5/2.75)) {
- return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
- } else {
- return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
- }
- },
- easeInOutBounce: function (x, t, b, c, d) {
- if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
- return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
- }
-});
-
-/*
- *
- * TERMS OF USE - EASING EQUATIONS
- *
- * Open source under the BSD License.
- *
- * Copyright © 2001 Robert Penner
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * Redistributions of source code must retain the above copyright notice, this list of
- * conditions and the following disclaimer.
- * Redistributions in binary form must reproduce the above copyright notice, this list
- * of conditions and the following disclaimer in the documentation and/or other materials
- * provided with the distribution.
- *
- * Neither the name of the author nor the names of contributors may be used to endorse
- * or promote products derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
- * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
- * OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */ \ No newline at end of file
diff --git a/app/assets/javascripts/vendor/fancybox/jquery.fancybox-1.3.4.pack.js b/app/assets/javascripts/vendor/fancybox/jquery.fancybox-1.3.4.pack.js
deleted file mode 100755
index 1373ed0..0000000
--- a/app/assets/javascripts/vendor/fancybox/jquery.fancybox-1.3.4.pack.js
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * FancyBox - jQuery Plugin
- * Simple and fancy lightbox alternative
- *
- * Examples and documentation at: http://fancybox.net
- *
- * Copyright (c) 2008 - 2010 Janis Skarnelis
- * That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
- *
- * Version: 1.3.4 (11/11/2010)
- * Requires: jQuery v1.3+
- *
- * Dual licensed under the MIT and GPL licenses:
- * http://www.opensource.org/licenses/mit-license.php
- * http://www.gnu.org/licenses/gpl.html
- */
-
-;(function(b){var m,t,u,f,D,j,E,n,z,A,q=0,e={},o=[],p=0,d={},l=[],G=null,v=new Image,J=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,W=/[^\.]\.(swf)\s*$/i,K,L=1,y=0,s="",r,i,h=false,B=b.extend(b("<div/>")[0],{prop:0}),M=b.browser.msie&&b.browser.version<7&&!window.XMLHttpRequest,N=function(){t.hide();v.onerror=v.onload=null;G&&G.abort();m.empty()},O=function(){if(false===e.onError(o,q,e)){t.hide();h=false}else{e.titleShow=false;e.width="auto";e.height="auto";m.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');
-F()}},I=function(){var a=o[q],c,g,k,C,P,w;N();e=b.extend({},b.fn.fancybox.defaults,typeof b(a).data("fancybox")=="undefined"?e:b(a).data("fancybox"));w=e.onStart(o,q,e);if(w===false)h=false;else{if(typeof w=="object")e=b.extend(e,w);k=e.title||(a.nodeName?b(a).attr("title"):a.title)||"";if(a.nodeName&&!e.orig)e.orig=b(a).children("img:first").length?b(a).children("img:first"):b(a);if(k===""&&e.orig&&e.titleFromAlt)k=e.orig.attr("alt");c=e.href||(a.nodeName?b(a).attr("href"):a.href)||null;if(/^(?:javascript)/i.test(c)||
-c=="#")c=null;if(e.type){g=e.type;if(!c)c=e.content}else if(e.content)g="html";else if(c)g=c.match(J)?"image":c.match(W)?"swf":b(a).hasClass("iframe")?"iframe":c.indexOf("#")===0?"inline":"ajax";if(g){if(g=="inline"){a=c.substr(c.indexOf("#"));g=b(a).length>0?"inline":"ajax"}e.type=g;e.href=c;e.title=k;if(e.autoDimensions)if(e.type=="html"||e.type=="inline"||e.type=="ajax"){e.width="auto";e.height="auto"}else e.autoDimensions=false;if(e.modal){e.overlayShow=true;e.hideOnOverlayClick=false;e.hideOnContentClick=
-false;e.enableEscapeButton=false;e.showCloseButton=false}e.padding=parseInt(e.padding,10);e.margin=parseInt(e.margin,10);m.css("padding",e.padding+e.margin);b(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){b(this).replaceWith(j.children())});switch(g){case "html":m.html(e.content);F();break;case "inline":if(b(a).parent().is("#fancybox-content")===true){h=false;break}b('<div class="fancybox-inline-tmp" />').hide().insertBefore(b(a)).bind("fancybox-cleanup",function(){b(this).replaceWith(j.children())}).bind("fancybox-cancel",
-function(){b(this).replaceWith(m.children())});b(a).appendTo(m);F();break;case "image":h=false;b.fancybox.showActivity();v=new Image;v.onerror=function(){O()};v.onload=function(){h=true;v.onerror=v.onload=null;e.width=v.width;e.height=v.height;b("<img />").attr({id:"fancybox-img",src:v.src,alt:e.title}).appendTo(m);Q()};v.src=c;break;case "swf":e.scrolling="no";C='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+e.width+'" height="'+e.height+'"><param name="movie" value="'+c+
-'"></param>';P="";b.each(e.swf,function(x,H){C+='<param name="'+x+'" value="'+H+'"></param>';P+=" "+x+'="'+H+'"'});C+='<embed src="'+c+'" type="application/x-shockwave-flash" width="'+e.width+'" height="'+e.height+'"'+P+"></embed></object>";m.html(C);F();break;case "ajax":h=false;b.fancybox.showActivity();e.ajax.win=e.ajax.success;G=b.ajax(b.extend({},e.ajax,{url:c,data:e.ajax.data||{},error:function(x){x.status>0&&O()},success:function(x,H,R){if((typeof R=="object"?R:G).status==200){if(typeof e.ajax.win==
-"function"){w=e.ajax.win(c,x,H,R);if(w===false){t.hide();return}else if(typeof w=="string"||typeof w=="object")x=w}m.html(x);F()}}}));break;case "iframe":Q()}}else O()}},F=function(){var a=e.width,c=e.height;a=a.toString().indexOf("%")>-1?parseInt((b(window).width()-e.margin*2)*parseFloat(a)/100,10)+"px":a=="auto"?"auto":a+"px";c=c.toString().indexOf("%")>-1?parseInt((b(window).height()-e.margin*2)*parseFloat(c)/100,10)+"px":c=="auto"?"auto":c+"px";m.wrapInner('<div style="width:'+a+";height:"+c+
-";overflow: "+(e.scrolling=="auto"?"auto":e.scrolling=="yes"?"scroll":"hidden")+';position:relative;"></div>');e.width=m.width();e.height=m.height();Q()},Q=function(){var a,c;t.hide();if(f.is(":visible")&&false===d.onCleanup(l,p,d)){b.event.trigger("fancybox-cancel");h=false}else{h=true;b(j.add(u)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");f.is(":visible")&&d.titlePosition!=="outside"&&f.css("height",f.height());l=o;p=q;d=e;if(d.overlayShow){u.css({"background-color":d.overlayColor,
-opacity:d.overlayOpacity,cursor:d.hideOnOverlayClick?"pointer":"auto",height:b(document).height()});if(!u.is(":visible")){M&&b("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"});u.show()}}else u.hide();i=X();s=d.title||"";y=0;n.empty().removeAttr("style").removeClass();if(d.titleShow!==false){if(b.isFunction(d.titleFormat))a=d.titleFormat(s,l,p,d);else a=s&&s.length?
-d.titlePosition=="float"?'<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">'+s+'</td><td id="fancybox-title-float-right"></td></tr></table>':'<div id="fancybox-title-'+d.titlePosition+'">'+s+"</div>":false;s=a;if(!(!s||s==="")){n.addClass("fancybox-title-"+d.titlePosition).html(s).appendTo("body").show();switch(d.titlePosition){case "inside":n.css({width:i.width-d.padding*2,marginLeft:d.padding,marginRight:d.padding});
-y=n.outerHeight(true);n.appendTo(D);i.height+=y;break;case "over":n.css({marginLeft:d.padding,width:i.width-d.padding*2,bottom:d.padding}).appendTo(D);break;case "float":n.css("left",parseInt((n.width()-i.width-40)/2,10)*-1).appendTo(f);break;default:n.css({width:i.width-d.padding*2,paddingLeft:d.padding,paddingRight:d.padding}).appendTo(f)}}}n.hide();if(f.is(":visible")){b(E.add(z).add(A)).hide();a=f.position();r={top:a.top,left:a.left,width:f.width(),height:f.height()};c=r.width==i.width&&r.height==
-i.height;j.fadeTo(d.changeFade,0.3,function(){var g=function(){j.html(m.contents()).fadeTo(d.changeFade,1,S)};b.event.trigger("fancybox-change");j.empty().removeAttr("filter").css({"border-width":d.padding,width:i.width-d.padding*2,height:e.autoDimensions?"auto":i.height-y-d.padding*2});if(c)g();else{B.prop=0;b(B).animate({prop:1},{duration:d.changeSpeed,easing:d.easingChange,step:T,complete:g})}})}else{f.removeAttr("style");j.css("border-width",d.padding);if(d.transitionIn=="elastic"){r=V();j.html(m.contents());
-f.show();if(d.opacity)i.opacity=0;B.prop=0;b(B).animate({prop:1},{duration:d.speedIn,easing:d.easingIn,step:T,complete:S})}else{d.titlePosition=="inside"&&y>0&&n.show();j.css({width:i.width-d.padding*2,height:e.autoDimensions?"auto":i.height-y-d.padding*2}).html(m.contents());f.css(i).fadeIn(d.transitionIn=="none"?0:d.speedIn,S)}}}},Y=function(){if(d.enableEscapeButton||d.enableKeyboardNav)b(document).bind("keydown.fb",function(a){if(a.keyCode==27&&d.enableEscapeButton){a.preventDefault();b.fancybox.close()}else if((a.keyCode==
-37||a.keyCode==39)&&d.enableKeyboardNav&&a.target.tagName!=="INPUT"&&a.target.tagName!=="TEXTAREA"&&a.target.tagName!=="SELECT"){a.preventDefault();b.fancybox[a.keyCode==37?"prev":"next"]()}});if(d.showNavArrows){if(d.cyclic&&l.length>1||p!==0)z.show();if(d.cyclic&&l.length>1||p!=l.length-1)A.show()}else{z.hide();A.hide()}},S=function(){if(!b.support.opacity){j.get(0).style.removeAttribute("filter");f.get(0).style.removeAttribute("filter")}e.autoDimensions&&j.css("height","auto");f.css("height","auto");
-s&&s.length&&n.show();d.showCloseButton&&E.show();Y();d.hideOnContentClick&&j.bind("click",b.fancybox.close);d.hideOnOverlayClick&&u.bind("click",b.fancybox.close);b(window).bind("resize.fb",b.fancybox.resize);d.centerOnScroll&&b(window).bind("scroll.fb",b.fancybox.center);if(d.type=="iframe")b('<iframe id="fancybox-frame" name="fancybox-frame'+(new Date).getTime()+'" frameborder="0" hspace="0" '+(b.browser.msie?'allowtransparency="true""':"")+' scrolling="'+e.scrolling+'" src="'+d.href+'"></iframe>').appendTo(j);
-f.show();h=false;b.fancybox.center();d.onComplete(l,p,d);var a,c;if(l.length-1>p){a=l[p+1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}if(p>0){a=l[p-1].href;if(typeof a!=="undefined"&&a.match(J)){c=new Image;c.src=a}}},T=function(a){var c={width:parseInt(r.width+(i.width-r.width)*a,10),height:parseInt(r.height+(i.height-r.height)*a,10),top:parseInt(r.top+(i.top-r.top)*a,10),left:parseInt(r.left+(i.left-r.left)*a,10)};if(typeof i.opacity!=="undefined")c.opacity=a<0.5?0.5:a;f.css(c);
-j.css({width:c.width-d.padding*2,height:c.height-y*a-d.padding*2})},U=function(){return[b(window).width()-d.margin*2,b(window).height()-d.margin*2,b(document).scrollLeft()+d.margin,b(document).scrollTop()+d.margin]},X=function(){var a=U(),c={},g=d.autoScale,k=d.padding*2;c.width=d.width.toString().indexOf("%")>-1?parseInt(a[0]*parseFloat(d.width)/100,10):d.width+k;c.height=d.height.toString().indexOf("%")>-1?parseInt(a[1]*parseFloat(d.height)/100,10):d.height+k;if(g&&(c.width>a[0]||c.height>a[1]))if(e.type==
-"image"||e.type=="swf"){g=d.width/d.height;if(c.width>a[0]){c.width=a[0];c.height=parseInt((c.width-k)/g+k,10)}if(c.height>a[1]){c.height=a[1];c.width=parseInt((c.height-k)*g+k,10)}}else{c.width=Math.min(c.width,a[0]);c.height=Math.min(c.height,a[1])}c.top=parseInt(Math.max(a[3]-20,a[3]+(a[1]-c.height-40)*0.5),10);c.left=parseInt(Math.max(a[2]-20,a[2]+(a[0]-c.width-40)*0.5),10);return c},V=function(){var a=e.orig?b(e.orig):false,c={};if(a&&a.length){c=a.offset();c.top+=parseInt(a.css("paddingTop"),
-10)||0;c.left+=parseInt(a.css("paddingLeft"),10)||0;c.top+=parseInt(a.css("border-top-width"),10)||0;c.left+=parseInt(a.css("border-left-width"),10)||0;c.width=a.width();c.height=a.height();c={width:c.width+d.padding*2,height:c.height+d.padding*2,top:c.top-d.padding-20,left:c.left-d.padding-20}}else{a=U();c={width:d.padding*2,height:d.padding*2,top:parseInt(a[3]+a[1]*0.5,10),left:parseInt(a[2]+a[0]*0.5,10)}}return c},Z=function(){if(t.is(":visible")){b("div",t).css("top",L*-40+"px");L=(L+1)%12}else clearInterval(K)};
-b.fn.fancybox=function(a){if(!b(this).length)return this;b(this).data("fancybox",b.extend({},a,b.metadata?b(this).metadata():{})).unbind("click.fb").bind("click.fb",function(c){c.preventDefault();if(!h){h=true;b(this).blur();o=[];q=0;c=b(this).attr("rel")||"";if(!c||c==""||c==="nofollow")o.push(this);else{o=b("a[rel="+c+"], area[rel="+c+"]");q=o.index(this)}I()}});return this};b.fancybox=function(a,c){var g;if(!h){h=true;g=typeof c!=="undefined"?c:{};o=[];q=parseInt(g.index,10)||0;if(b.isArray(a)){for(var k=
-0,C=a.length;k<C;k++)if(typeof a[k]=="object")b(a[k]).data("fancybox",b.extend({},g,a[k]));else a[k]=b({}).data("fancybox",b.extend({content:a[k]},g));o=jQuery.merge(o,a)}else{if(typeof a=="object")b(a).data("fancybox",b.extend({},g,a));else a=b({}).data("fancybox",b.extend({content:a},g));o.push(a)}if(q>o.length||q<0)q=0;I()}};b.fancybox.showActivity=function(){clearInterval(K);t.show();K=setInterval(Z,66)};b.fancybox.hideActivity=function(){t.hide()};b.fancybox.next=function(){return b.fancybox.pos(p+
-1)};b.fancybox.prev=function(){return b.fancybox.pos(p-1)};b.fancybox.pos=function(a){if(!h){a=parseInt(a);o=l;if(a>-1&&a<l.length){q=a;I()}else if(d.cyclic&&l.length>1){q=a>=l.length?0:l.length-1;I()}}};b.fancybox.cancel=function(){if(!h){h=true;b.event.trigger("fancybox-cancel");N();e.onCancel(o,q,e);h=false}};b.fancybox.close=function(){function a(){u.fadeOut("fast");n.empty().hide();f.hide();b.event.trigger("fancybox-cleanup");j.empty();d.onClosed(l,p,d);l=e=[];p=q=0;d=e={};h=false}if(!(h||f.is(":hidden"))){h=
-true;if(d&&false===d.onCleanup(l,p,d))h=false;else{N();b(E.add(z).add(A)).hide();b(j.add(u)).unbind();b(window).unbind("resize.fb scroll.fb");b(document).unbind("keydown.fb");j.find("iframe").attr("src",M&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");d.titlePosition!=="inside"&&n.empty();f.stop();if(d.transitionOut=="elastic"){r=V();var c=f.position();i={top:c.top,left:c.left,width:f.width(),height:f.height()};if(d.opacity)i.opacity=1;n.empty().hide();B.prop=1;
-b(B).animate({prop:0},{duration:d.speedOut,easing:d.easingOut,step:T,complete:a})}else f.fadeOut(d.transitionOut=="none"?0:d.speedOut,a)}}};b.fancybox.resize=function(){u.is(":visible")&&u.css("height",b(document).height());b.fancybox.center(true)};b.fancybox.center=function(a){var c,g;if(!h){g=a===true?1:0;c=U();!g&&(f.width()>c[0]||f.height()>c[1])||f.stop().animate({top:parseInt(Math.max(c[3]-20,c[3]+(c[1]-j.height()-40)*0.5-d.padding)),left:parseInt(Math.max(c[2]-20,c[2]+(c[0]-j.width()-40)*0.5-
-d.padding))},typeof a=="number"?a:200)}};b.fancybox.init=function(){if(!b("#fancybox-wrap").length){b("body").append(m=b('<div id="fancybox-tmp"></div>'),t=b('<div id="fancybox-loading"><div></div></div>'),u=b('<div id="fancybox-overlay"></div>'),f=b('<div id="fancybox-wrap"></div>'));D=b('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(f);
-D.append(j=b('<div id="fancybox-content"></div>'),E=b('<a id="fancybox-close"></a>'),n=b('<div id="fancybox-title"></div>'),z=b('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),A=b('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));E.click(b.fancybox.close);t.click(b.fancybox.cancel);z.click(function(a){a.preventDefault();b.fancybox.prev()});A.click(function(a){a.preventDefault();b.fancybox.next()});
-b.fn.mousewheel&&f.bind("mousewheel.fb",function(a,c){if(h)a.preventDefault();else if(b(a.target).get(0).clientHeight==0||b(a.target).get(0).scrollHeight===b(a.target).get(0).clientHeight){a.preventDefault();b.fancybox[c>0?"prev":"next"]()}});b.support.opacity||f.addClass("fancybox-ie");if(M){t.addClass("fancybox-ie6");f.addClass("fancybox-ie6");b('<iframe id="fancybox-hide-sel-frame" src="'+(/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank")+'" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(D)}}};
-b.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",
-easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};b(document).ready(function(){b.fancybox.init()})})(jQuery); \ No newline at end of file
diff --git a/app/assets/javascripts/vendor/fancybox/jquery.mousewheel-3.0.4.pack.js b/app/assets/javascripts/vendor/fancybox/jquery.mousewheel-3.0.4.pack.js
deleted file mode 100755
index cb66588..0000000
--- a/app/assets/javascripts/vendor/fancybox/jquery.mousewheel-3.0.4.pack.js
+++ /dev/null
@@ -1,14 +0,0 @@
-/*! Copyright (c) 2010 Brandon Aaron (http://brandonaaron.net)
-* Licensed under the MIT License (LICENSE.txt).
-*
-* Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
-* Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
-* Thanks to: Seamus Leahy for adding deltaX and deltaY
-*
-* Version: 3.0.4
-*
-* Requires: 1.2.2+
-*/
-
-(function(d){function g(a){var b=a||window.event,i=[].slice.call(arguments,1),c=0,h=0,e=0;a=d.event.fix(b);a.type="mousewheel";if(a.wheelDelta)c=a.wheelDelta/120;if(a.detail)c=-a.detail/3;e=c;if(b.axis!==undefined&&b.axis===b.HORIZONTAL_AXIS){e=0;h=-1*c}if(b.wheelDeltaY!==undefined)e=b.wheelDeltaY/120;if(b.wheelDeltaX!==undefined)h=-1*b.wheelDeltaX/120;i.unshift(a,c,h,e);return d.event.handle.apply(this,i)}var f=["DOMMouseScroll","mousewheel"];d.event.special.mousewheel={setup:function(){if(this.addEventListener)for(var a=
-f.length;a;)this.addEventListener(f[--a],g,false);else this.onmousewheel=g},teardown:function(){if(this.removeEventListener)for(var a=f.length;a;)this.removeEventListener(f[--a],g,false);else this.onmousewheel=null}};d.fn.extend({mousewheel:function(a){return a?this.bind("mousewheel",a):this.trigger("mousewheel")},unmousewheel:function(a){return this.unbind("mousewheel",a)}})})(jQuery); \ No newline at end of file
diff --git a/app/assets/javascripts/vendor/html5boilerplate.js b/app/assets/javascripts/vendor/html5boilerplate.js
deleted file mode 100644
index 7cb21b1..0000000
--- a/app/assets/javascripts/vendor/html5boilerplate.js
+++ /dev/null
@@ -1,20 +0,0 @@
-
-// usage: log('inside coolFunc', this, arguments);
-// paulirish.com/2009/log-a-lightweight-wrapper-for-consolelog/
-window.log = function(){
- log.history = log.history || []; // store logs to an array for reference
- log.history.push(arguments);
- if(this.console) {
- arguments.callee = arguments.callee.caller;
- var newarr = [].slice.call(arguments);
- (typeof console.log === 'object' ? log.apply.call(console.log, console, newarr) : console.log.apply(console, newarr));
- }
-};
-
-// make it safe to use console.log always
-(function(b){function c(){}for(var d="assert,count,debug,dir,dirxml,error,exception,group,groupCollapsed,groupEnd,info,log,timeStamp,profile,profileEnd,time,timeEnd,trace,warn".split(","),a;a=d.pop();){b[a]=b[a]||c}})((function(){try
-{console.log();return window.console;}catch(err){return window.console={};}})());
-
-
-// place any jQuery/helper plugins in here, instead of separate, slower script files.
-
diff --git a/app/assets/javascripts/vendor/jquery-1.6.2.min.js b/app/assets/javascripts/vendor/jquery-1.6.2.min.js
deleted file mode 100755
index 48590ec..0000000
--- a/app/assets/javascripts/vendor/jquery-1.6.2.min.js
+++ /dev/null
@@ -1,18 +0,0 @@
-/*!
- * jQuery JavaScript Library v1.6.2
- * http://jquery.com/
- *
- * Copyright 2011, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- * http://jquery.org/license
- *
- * Includes Sizzle.js
- * http://sizzlejs.com/
- * Copyright 2011, The Dojo Foundation
- * Released under the MIT, BSD, and GPL Licenses.
- *
- * Date: Thu Jun 30 14:16:56 2011 -0400
- */
-(function(a,b){function cv(a){return f.isWindow(a)?a:a.nodeType===9?a.defaultView||a.parentWindow:!1}function cs(a){if(!cg[a]){var b=c.body,d=f("<"+a+">").appendTo(b),e=d.css("display");d.remove();if(e==="none"||e===""){ch||(ch=c.createElement("iframe"),ch.frameBorder=ch.width=ch.height=0),b.appendChild(ch);if(!ci||!ch.createElement)ci=(ch.contentWindow||ch.contentDocument).document,ci.write((c.compatMode==="CSS1Compat"?"<!doctype html>":"")+"<html><body>"),ci.close();d=ci.createElement(a),ci.body.appendChild(d),e=f.css(d,"display"),b.removeChild(ch)}cg[a]=e}return cg[a]}function cr(a,b){var c={};f.each(cm.concat.apply([],cm.slice(0,b)),function(){c[this]=a});return c}function cq(){cn=b}function cp(){setTimeout(cq,0);return cn=f.now()}function cf(){try{return new a.ActiveXObject("Microsoft.XMLHTTP")}catch(b){}}function ce(){try{return new a.XMLHttpRequest}catch(b){}}function b$(a,c){a.dataFilter&&(c=a.dataFilter(c,a.dataType));var d=a.dataTypes,e={},g,h,i=d.length,j,k=d[0],l,m,n,o,p;for(g=1;g<i;g++){if(g===1)for(h in a.converters)typeof h=="string"&&(e[h.toLowerCase()]=a.converters[h]);l=k,k=d[g];if(k==="*")k=l;else if(l!=="*"&&l!==k){m=l+" "+k,n=e[m]||e["* "+k];if(!n){p=b;for(o in e){j=o.split(" ");if(j[0]===l||j[0]==="*"){p=e[j[1]+" "+k];if(p){o=e[o],o===!0?n=p:p===!0&&(n=o);break}}}}!n&&!p&&f.error("No conversion from "+m.replace(" "," to ")),n!==!0&&(c=n?n(c):p(o(c)))}}return c}function bZ(a,c,d){var e=a.contents,f=a.dataTypes,g=a.responseFields,h,i,j,k;for(i in g)i in d&&(c[g[i]]=d[i]);while(f[0]==="*")f.shift(),h===b&&(h=a.mimeType||c.getResponseHeader("content-type"));if(h)for(i in e)if(e[i]&&e[i].test(h)){f.unshift(i);break}if(f[0]in d)j=f[0];else{for(i in d){if(!f[0]||a.converters[i+" "+f[0]]){j=i;break}k||(k=i)}j=j||k}if(j){j!==f[0]&&f.unshift(j);return d[j]}}function bY(a,b,c,d){if(f.isArray(b))f.each(b,function(b,e){c||bC.test(a)?d(a,e):bY(a+"["+(typeof e=="object"||f.isArray(e)?b:"")+"]",e,c,d)});else if(!c&&b!=null&&typeof b=="object")for(var e in b)bY(a+"["+e+"]",b[e],c,d);else d(a,b)}function bX(a,c,d,e,f,g){f=f||c.dataTypes[0],g=g||{},g[f]=!0;var h=a[f],i=0,j=h?h.length:0,k=a===bR,l;for(;i<j&&(k||!l);i++)l=h[i](c,d,e),typeof l=="string"&&(!k||g[l]?l=b:(c.dataTypes.unshift(l),l=bX(a,c,d,e,l,g)));(k||!l)&&!g["*"]&&(l=bX(a,c,d,e,"*",g));return l}function bW(a){return function(b,c){typeof b!="string"&&(c=b,b="*");if(f.isFunction(c)){var d=b.toLowerCase().split(bN),e=0,g=d.length,h,i,j;for(;e<g;e++)h=d[e],j=/^\+/.test(h),j&&(h=h.substr(1)||"*"),i=a[h]=a[h]||[],i[j?"unshift":"push"](c)}}}function bA(a,b,c){var d=b==="width"?a.offsetWidth:a.offsetHeight,e=b==="width"?bv:bw;if(d>0){c!=="border"&&f.each(e,function(){c||(d-=parseFloat(f.css(a,"padding"+this))||0),c==="margin"?d+=parseFloat(f.css(a,c+this))||0:d-=parseFloat(f.css(a,"border"+this+"Width"))||0});return d+"px"}d=bx(a,b,b);if(d<0||d==null)d=a.style[b]||0;d=parseFloat(d)||0,c&&f.each(e,function(){d+=parseFloat(f.css(a,"padding"+this))||0,c!=="padding"&&(d+=parseFloat(f.css(a,"border"+this+"Width"))||0),c==="margin"&&(d+=parseFloat(f.css(a,c+this))||0)});return d+"px"}function bm(a,b){b.src?f.ajax({url:b.src,async:!1,dataType:"script"}):f.globalEval((b.text||b.textContent||b.innerHTML||"").replace(be,"/*$0*/")),b.parentNode&&b.parentNode.removeChild(b)}function bl(a){f.nodeName(a,"input")?bk(a):"getElementsByTagName"in a&&f.grep(a.getElementsByTagName("input"),bk)}function bk(a){if(a.type==="checkbox"||a.type==="radio")a.defaultChecked=a.checked}function bj(a){return"getElementsByTagName"in a?a.getElementsByTagName("*"):"querySelectorAll"in a?a.querySelectorAll("*"):[]}function bi(a,b){var c;if(b.nodeType===1){b.clearAttributes&&b.clearAttributes(),b.mergeAttributes&&b.mergeAttributes(a),c=b.nodeName.toLowerCase();if(c==="object")b.outerHTML=a.outerHTML;else if(c!=="input"||a.type!=="checkbox"&&a.type!=="radio"){if(c==="option")b.selected=a.defaultSelected;else if(c==="input"||c==="textarea")b.defaultValue=a.defaultValue}else a.checked&&(b.defaultChecked=b.checked=a.checked),b.value!==a.value&&(b.value=a.value);b.removeAttribute(f.expando)}}function bh(a,b){if(b.nodeType===1&&!!f.hasData(a)){var c=f.expando,d=f.data(a),e=f.data(b,d);if(d=d[c]){var g=d.events;e=e[c]=f.extend({},d);if(g){delete e.handle,e.events={};for(var h in g)for(var i=0,j=g[h].length;i<j;i++)f.event.add(b,h+(g[h][i].namespace?".":"")+g[h][i].namespace,g[h][i],g[h][i].data)}}}}function bg(a,b){return f.nodeName(a,"table")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function W(a,b,c){b=b||0;if(f.isFunction(b))return f.grep(a,function(a,d){var e=!!b.call(a,d,a);return e===c});if(b.nodeType)return f.grep(a,function(a,d){return a===b===c});if(typeof b=="string"){var d=f.grep(a,function(a){return a.nodeType===1});if(R.test(b))return f.filter(b,d,!c);b=f.filter(b,d)}return f.grep(a,function(a,d){return f.inArray(a,b)>=0===c})}function V(a){return!a||!a.parentNode||a.parentNode.nodeType===11}function N(a,b){return(a&&a!=="*"?a+".":"")+b.replace(z,"`").replace(A,"&")}function M(a){var b,c,d,e,g,h,i,j,k,l,m,n,o,p=[],q=[],r=f._data(this,"events");if(!(a.liveFired===this||!r||!r.live||a.target.disabled||a.button&&a.type==="click")){a.namespace&&(n=new RegExp("(^|\\.)"+a.namespace.split(".").join("\\.(?:.*\\.)?")+"(\\.|$)")),a.liveFired=this;var s=r.live.slice(0);for(i=0;i<s.length;i++)g=s[i],g.origType.replace(x,"")===a.type?q.push(g.selector):s.splice(i--,1);e=f(a.target).closest(q,a.currentTarget);for(j=0,k=e.length;j<k;j++){m=e[j];for(i=0;i<s.length;i++){g=s[i];if(m.selector===g.selector&&(!n||n.test(g.namespace))&&!m.elem.disabled){h=m.elem,d=null;if(g.preType==="mouseenter"||g.preType==="mouseleave")a.type=g.preType,d=f(a.relatedTarget).closest(g.selector)[0],d&&f.contains(h,d)&&(d=h);(!d||d!==h)&&p.push({elem:h,handleObj:g,level:m.level})}}}for(j=0,k=p.length;j<k;j++){e=p[j];if(c&&e.level>c)break;a.currentTarget=e.elem,a.data=e.handleObj.data,a.handleObj=e.handleObj,o=e.handleObj.origHandler.apply(e.elem,arguments);if(o===!1||a.isPropagationStopped()){c=e.level,o===!1&&(b=!1);if(a.isImmediatePropagationStopped())break}}return b}}function K(a,c,d){var e=f.extend({},d[0]);e.type=a,e.originalEvent={},e.liveFired=b,f.event.handle.call(c,e),e.isDefaultPrevented()&&d[0].preventDefault()}function E(){return!0}function D(){return!1}function m(a,c,d){var e=c+"defer",g=c+"queue",h=c+"mark",i=f.data(a,e,b,!0);i&&(d==="queue"||!f.data(a,g,b,!0))&&(d==="mark"||!f.data(a,h,b,!0))&&setTimeout(function(){!f.data(a,g,b,!0)&&!f.data(a,h,b,!0)&&(f.removeData(a,e,!0),i.resolve())},0)}function l(a){for(var b in a)if(b!=="toJSON")return!1;return!0}function k(a,c,d){if(d===b&&a.nodeType===1){var e="data-"+c.replace(j,"$1-$2").toLowerCase();d=a.getAttribute(e);if(typeof d=="string"){try{d=d==="true"?!0:d==="false"?!1:d==="null"?null:f.isNaN(d)?i.test(d)?f.parseJSON(d):d:parseFloat(d)}catch(g){}f.data(a,c,d)}else d=b}return d}var c=a.document,d=a.navigator,e=a.location,f=function(){function J(){if(!e.isReady){try{c.documentElement.doScroll("left")}catch(a){setTimeout(J,1);return}e.ready()}}var e=function(a,b){return new e.fn.init(a,b,h)},f=a.jQuery,g=a.$,h,i=/^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,j=/\S/,k=/^\s+/,l=/\s+$/,m=/\d/,n=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,o=/^[\],:{}\s]*$/,p=/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,q=/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,r=/(?:^|:|,)(?:\s*\[)+/g,s=/(webkit)[ \/]([\w.]+)/,t=/(opera)(?:.*version)?[ \/]([\w.]+)/,u=/(msie) ([\w.]+)/,v=/(mozilla)(?:.*? rv:([\w.]+))?/,w=/-([a-z])/ig,x=function(a,b){return b.toUpperCase()},y=d.userAgent,z,A,B,C=Object.prototype.toString,D=Object.prototype.hasOwnProperty,E=Array.prototype.push,F=Array.prototype.slice,G=String.prototype.trim,H=Array.prototype.indexOf,I={};e.fn=e.prototype={constructor:e,init:function(a,d,f){var g,h,j,k;if(!a)return this;if(a.nodeType){this.context=this[0]=a,this.length=1;return this}if(a==="body"&&!d&&c.body){this.context=c,this[0]=c.body,this.selector=a,this.length=1;return this}if(typeof a=="string"){a.charAt(0)!=="<"||a.charAt(a.length-1)!==">"||a.length<3?g=i.exec(a):g=[null,a,null];if(g&&(g[1]||!d)){if(g[1]){d=d instanceof e?d[0]:d,k=d?d.ownerDocument||d:c,j=n.exec(a),j?e.isPlainObject(d)?(a=[c.createElement(j[1])],e.fn.attr.call(a,d,!0)):a=[k.createElement(j[1])]:(j=e.buildFragment([g[1]],[k]),a=(j.cacheable?e.clone(j.fragment):j.fragment).childNodes);return e.merge(this,a)}h=c.getElementById(g[2]);if(h&&h.parentNode){if(h.id!==g[2])return f.find(a);this.length=1,this[0]=h}this.context=c,this.selector=a;return this}return!d||d.jquery?(d||f).find(a):this.constructor(d).find(a)}if(e.isFunction(a))return f.ready(a);a.selector!==b&&(this.selector=a.selector,this.context=a.context);return e.makeArray(a,this)},selector:"",jquery:"1.6.2",length:0,size:function(){return this.length},toArray:function(){return F.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this[this.length+a]:this[a]},pushStack:function(a,b,c){var d=this.constructor();e.isArray(a)?E.apply(d,a):e.merge(d,a),d.prevObject=this,d.context=this.context,b==="find"?d.selector=this.selector+(this.selector?" ":"")+c:b&&(d.selector=this.selector+"."+b+"("+c+")");return d},each:function(a,b){return e.each(this,a,b)},ready:function(a){e.bindReady(),A.done(a);return this},eq:function(a){return a===-1?this.slice(a):this.slice(a,+a+1)},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},slice:function(){return this.pushStack(F.apply(this,arguments),"slice",F.call(arguments).join(","))},map:function(a){return this.pushStack(e.map(this,function(b,c){return a.call(b,c,b)}))},end:function(){return this.prevObject||this.constructor(null)},push:E,sort:[].sort,splice:[].splice},e.fn.init.prototype=e.fn,e.extend=e.fn.extend=function(){var a,c,d,f,g,h,i=arguments[0]||{},j=1,k=arguments.length,l=!1;typeof i=="boolean"&&(l=i,i=arguments[1]||{},j=2),typeof i!="object"&&!e.isFunction(i)&&(i={}),k===j&&(i=this,--j);for(;j<k;j++)if((a=arguments[j])!=null)for(c in a){d=i[c],f=a[c];if(i===f)continue;l&&f&&(e.isPlainObject(f)||(g=e.isArray(f)))?(g?(g=!1,h=d&&e.isArray(d)?d:[]):h=d&&e.isPlainObject(d)?d:{},i[c]=e.extend(l,h,f)):f!==b&&(i[c]=f)}return i},e.extend({noConflict:function(b){a.$===e&&(a.$=g),b&&a.jQuery===e&&(a.jQuery=f);return e},isReady:!1,readyWait:1,holdReady:function(a){a?e.readyWait++:e.ready(!0)},ready:function(a){if(a===!0&&!--e.readyWait||a!==!0&&!e.isReady){if(!c.body)return setTimeout(e.ready,1);e.isReady=!0;if(a!==!0&&--e.readyWait>0)return;A.resolveWith(c,[e]),e.fn.trigger&&e(c).trigger("ready").unbind("ready")}},bindReady:function(){if(!A){A=e._Deferred();if(c.readyState==="complete")return setTimeout(e.ready,1);if(c.addEventListener)c.addEventListener("DOMContentLoaded",B,!1),a.addEventListener("load",e.ready,!1);else if(c.attachEvent){c.attachEvent("onreadystatechange",B),a.attachEvent("onload",e.ready);var b=!1;try{b=a.frameElement==null}catch(d){}c.documentElement.doScroll&&b&&J()}}},isFunction:function(a){return e.type(a)==="function"},isArray:Array.isArray||function(a){return e.type(a)==="array"},isWindow:function(a){return a&&typeof a=="object"&&"setInterval"in a},isNaN:function(a){return a==null||!m.test(a)||isNaN(a)},type:function(a){return a==null?String(a):I[C.call(a)]||"object"},isPlainObject:function(a){if(!a||e.type(a)!=="object"||a.nodeType||e.isWindow(a))return!1;if(a.constructor&&!D.call(a,"constructor")&&!D.call(a.constructor.prototype,"isPrototypeOf"))return!1;var c;for(c in a);return c===b||D.call(a,c)},isEmptyObject:function(a){for(var b in a)return!1;return!0},error:function(a){throw a},parseJSON:function(b){if(typeof b!="string"||!b)return null;b=e.trim(b);if(a.JSON&&a.JSON.parse)return a.JSON.parse(b);if(o.test(b.replace(p,"@").replace(q,"]").replace(r,"")))return(new Function("return "+b))();e.error("Invalid JSON: "+b)},parseXML:function(b,c,d){a.DOMParser?(d=new DOMParser,c=d.parseFromString(b,"text/xml")):(c=new ActiveXObject("Microsoft.XMLDOM"),c.async="false",c.loadXML(b)),d=c.documentElement,(!d||!d.nodeName||d.nodeName==="parsererror")&&e.error("Invalid XML: "+b);return c},noop:function(){},globalEval:function(b){b&&j.test(b)&&(a.execScript||function(b){a.eval.call(a,b)})(b)},camelCase:function(a){return a.replace(w,x)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toUpperCase()===b.toUpperCase()},each:function(a,c,d){var f,g=0,h=a.length,i=h===b||e.isFunction(a);if(d){if(i){for(f in a)if(c.apply(a[f],d)===!1)break}else for(;g<h;)if(c.apply(a[g++],d)===!1)break}else if(i){for(f in a)if(c.call(a[f],f,a[f])===!1)break}else for(;g<h;)if(c.call(a[g],g,a[g++])===!1)break;return a},trim:G?function(a){return a==null?"":G.call(a)}:function(a){return a==null?"":(a+"").replace(k,"").replace(l,"")},makeArray:function(a,b){var c=b||[];if(a!=null){var d=e.type(a);a.length==null||d==="string"||d==="function"||d==="regexp"||e.isWindow(a)?E.call(c,a):e.merge(c,a)}return c},inArray:function(a,b){if(H)return H.call(b,a);for(var c=0,d=b.length;c<d;c++)if(b[c]===a)return c;return-1},merge:function(a,c){var d=a.length,e=0;if(typeof c.length=="number")for(var f=c.length;e<f;e++)a[d++]=c[e];else while(c[e]!==b)a[d++]=c[e++];a.length=d;return a},grep:function(a,b,c){var d=[],e;c=!!c;for(var f=0,g=a.length;f<g;f++)e=!!b(a[f],f),c!==e&&d.push(a[f]);return d},map:function(a,c,d){var f,g,h=[],i=0,j=a.length,k=a instanceof e||j!==b&&typeof j=="number"&&(j>0&&a[0]&&a[j-1]||j===0||e.isArray(a));if(k)for(;i<j;i++)f=c(a[i],i,d),f!=null&&(h[h.length]=f);else for(g in a)f=c(a[g],g,d),f!=null&&(h[h.length]=f);return h.concat.apply([],h)},guid:1,proxy:function(a,c){if(typeof c=="string"){var d=a[c];c=a,a=d}if(!e.isFunction(a))return b;var f=F.call(arguments,2),g=function(){return a.apply(c,f.concat(F.call(arguments)))};g.guid=a.guid=a.guid||g.guid||e.guid++;return g},access:function(a,c,d,f,g,h){var i=a.length;if(typeof c=="object"){for(var j in c)e.access(a,j,c[j],f,g,d);return a}if(d!==b){f=!h&&f&&e.isFunction(d);for(var k=0;k<i;k++)g(a[k],c,f?d.call(a[k],k,g(a[k],c)):d,h);return a}return i?g(a[0],c):b},now:function(){return(new Date).getTime()},uaMatch:function(a){a=a.toLowerCase();var b=s.exec(a)||t.exec(a)||u.exec(a)||a.indexOf("compatible")<0&&v.exec(a)||[];return{browser:b[1]||"",version:b[2]||"0"}},sub:function(){function a(b,c){return new a.fn.init(b,c)}e.extend(!0,a,this),a.superclass=this,a.fn=a.prototype=this(),a.fn.constructor=a,a.sub=this.sub,a.fn.init=function(d,f){f&&f instanceof e&&!(f instanceof a)&&(f=a(f));return e.fn.init.call(this,d,f,b)},a.fn.init.prototype=a.fn;var b=a(c);return a},browser:{}}),e.each("Boolean Number String Function Array Date RegExp Object".split(" "),function(a,b){I["[object "+b+"]"]=b.toLowerCase()}),z=e.uaMatch(y),z.browser&&(e.browser[z.browser]=!0,e.browser.version=z.version),e.browser.webkit&&(e.browser.safari=!0),j.test(" ")&&(k=/^[\s\xA0]+/,l=/[\s\xA0]+$/),h=e(c),c.addEventListener?B=function(){c.removeEventListener("DOMContentLoaded",B,!1),e.ready()}:c.attachEvent&&(B=function(){c.readyState==="complete"&&(c.detachEvent("onreadystatechange",B),e.ready())});return e}(),g="done fail isResolved isRejected promise then always pipe".split(" "),h=[].slice;f.extend({_Deferred:function(){var a=[],b,c,d,e={done:function(){if(!d){var c=arguments,g,h,i,j,k;b&&(k=b,b=0);for(g=0,h=c.length;g<h;g++)i=c[g],j=f.type(i),j==="array"?e.done.apply(e,i):j==="function"&&a.push(i);k&&e.resolveWith(k[0],k[1])}return this},resolveWith:function(e,f){if(!d&&!b&&!c){f=f||[],c=1;try{while(a[0])a.shift().apply(e,f)}finally{b=[e,f],c=0}}return this},resolve:function(){e.resolveWith(this,arguments);return this},isResolved:function(){return!!c||!!b},cancel:function(){d=1,a=[];return this}};return e},Deferred:function(a){var b=f._Deferred(),c=f._Deferred(),d;f.extend(b,{then:function(a,c){b.done(a).fail(c);return this},always:function(){return b.done.apply(b,arguments).fail.apply(this,arguments)},fail:c.done,rejectWith:c.resolveWith,reject:c.resolve,isRejected:c.isResolved,pipe:function(a,c){return f.Deferred(function(d){f.each({done:[a,"resolve"],fail:[c,"reject"]},function(a,c){var e=c[0],g=c[1],h;f.isFunction(e)?b[a](function(){h=e.apply(this,arguments),h&&f.isFunction(h.promise)?h.promise().then(d.resolve,d.reject):d[g](h)}):b[a](d[g])})}).promise()},promise:function(a){if(a==null){if(d)return d;d=a={}}var c=g.length;while(c--)a[g[c]]=b[g[c]];return a}}),b.done(c.cancel).fail(b.cancel),delete b.cancel,a&&a.call(b,b);return b},when:function(a){function i(a){return function(c){b[a]=arguments.length>1?h.call(arguments,0):c,--e||g.resolveWith(g,h.call(b,0))}}var b=arguments,c=0,d=b.length,e=d,g=d<=1&&a&&f.isFunction(a.promise)?a:f.Deferred();if(d>1){for(;c<d;c++)b[c]&&f.isFunction(b[c].promise)?b[c].promise().then(i(c),g.reject):--e;e||g.resolveWith(g,b)}else g!==a&&g.resolveWith(g,d?[a]:[]);return g.promise()}}),f.support=function(){var a=c.createElement("div"),b=c.documentElement,d,e,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u;a.setAttribute("className","t"),a.innerHTML=" <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>",d=a.getElementsByTagName("*"),e=a.getElementsByTagName("a")[0];if(!d||!d.length||!e)return{};g=c.createElement("select"),h=g.appendChild(c.createElement("option")),i=a.getElementsByTagName("input")[0],k={leadingWhitespace:a.firstChild.nodeType===3,tbody:!a.getElementsByTagName("tbody").length,htmlSerialize:!!a.getElementsByTagName("link").length,style:/top/.test(e.getAttribute("style")),hrefNormalized:e.getAttribute("href")==="/a",opacity:/^0.55$/.test(e.style.opacity),cssFloat:!!e.style.cssFloat,checkOn:i.value==="on",optSelected:h.selected,getSetAttribute:a.className!=="t",submitBubbles:!0,changeBubbles:!0,focusinBubbles:!1,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0},i.checked=!0,k.noCloneChecked=i.cloneNode(!0).checked,g.disabled=!0,k.optDisabled=!h.disabled;try{delete a.test}catch(v){k.deleteExpando=!1}!a.addEventListener&&a.attachEvent&&a.fireEvent&&(a.attachEvent("onclick",function(){k.noCloneEvent=!1}),a.cloneNode(!0).fireEvent("onclick")),i=c.createElement("input"),i.value="t",i.setAttribute("type","radio"),k.radioValue=i.value==="t",i.setAttribute("checked","checked"),a.appendChild(i),l=c.createDocumentFragment(),l.appendChild(a.firstChild),k.checkClone=l.cloneNode(!0).cloneNode(!0).lastChild.checked,a.innerHTML="",a.style.width=a.style.paddingLeft="1px",m=c.getElementsByTagName("body")[0],o=c.createElement(m?"div":"body"),p={visibility:"hidden",width:0,height:0,border:0,margin:0},m&&f.extend(p,{position:"absolute",left:-1e3,top:-1e3});for(t in p)o.style[t]=p[t];o.appendChild(a),n=m||b,n.insertBefore(o,n.firstChild),k.appendChecked=i.checked,k.boxModel=a.offsetWidth===2,"zoom"in a.style&&(a.style.display="inline",a.style.zoom=1,k.inlineBlockNeedsLayout=a.offsetWidth===2,a.style.display="",a.innerHTML="<div style='width:4px;'></div>",k.shrinkWrapBlocks=a.offsetWidth!==2),a.innerHTML="<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>",q=a.getElementsByTagName("td"),u=q[0].offsetHeight===0,q[0].style.display="",q[1].style.display="none",k.reliableHiddenOffsets=u&&q[0].offsetHeight===0,a.innerHTML="",c.defaultView&&c.defaultView.getComputedStyle&&(j=c.createElement("div"),j.style.width="0",j.style.marginRight="0",a.appendChild(j),k.reliableMarginRight=(parseInt((c.defaultView.getComputedStyle(j,null)||{marginRight:0}).marginRight,10)||0)===0),o.innerHTML="",n.removeChild(o);if(a.attachEvent)for(t in{submit:1,change:1,focusin:1})s="on"+t,u=s in a,u||(a.setAttribute(s,"return;"),u=typeof a[s]=="function"),k[t+"Bubbles"]=u;o=l=g=h=m=j=a=i=null;return k}(),f.boxModel=f.support.boxModel;var i=/^(?:\{.*\}|\[.*\])$/,j=/([a-z])([A-Z])/g;f.extend({cache:{},uuid:0,expando:"jQuery"+(f.fn.jquery+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(a){a=a.nodeType?f.cache[a[f.expando]]:a[f.expando];return!!a&&!l(a)},data:function(a,c,d,e){if(!!f.acceptData(a)){var g=f.expando,h=typeof c=="string",i,j=a.nodeType,k=j?f.cache:a,l=j?a[f.expando]:a[f.expando]&&f.expando;if((!l||e&&l&&!k[l][g])&&h&&d===b)return;l||(j?a[f.expando]=l=++f.uuid:l=f.expando),k[l]||(k[l]={},j||(k[l].toJSON=f.noop));if(typeof c=="object"||typeof c=="function")e?k[l][g]=f.extend(k[l][g],c):k[l]=f.extend(k[l],c);i=k[l],e&&(i[g]||(i[g]={}),i=i[g]),d!==b&&(i[f.camelCase(c)]=d);if(c==="events"&&!i[c])return i[g]&&i[g].events;return h?i[f.camelCase(c)]||i[c]:i}},removeData:function(b,c,d){if(!!f.acceptData(b)){var e=f.expando,g=b.nodeType,h=g?f.cache:b,i=g?b[f.expando]:f.expando;if(!h[i])return;if(c){var j=d?h[i][e]:h[i];if(j){delete j[c];if(!l(j))return}}if(d){delete h[i][e];if(!l(h[i]))return}var k=h[i][e];f.support.deleteExpando||h!=a?delete h[i]:h[i]=null,k?(h[i]={},g||(h[i].toJSON=f.noop),h[i][e]=k):g&&(f.support.deleteExpando?delete b[f.expando]:b.removeAttribute?b.removeAttribute(f.expando):b[f.expando]=null)}},_data:function(a,b,c){return f.data(a,b,c,!0)},acceptData:function(a){if(a.nodeName){var b=f.noData[a.nodeName.toLowerCase()];if(b)return b!==!0&&a.getAttribute("classid")===b}return!0}}),f.fn.extend({data:function(a,c){var d=null;if(typeof a=="undefined"){if(this.length){d=f.data(this[0]);if(this[0].nodeType===1){var e=this[0].attributes,g;for(var h=0,i=e.length;h<i;h++)g=e[h].name,g.indexOf("data-")===0&&(g=f.camelCase(g.substring(5)),k(this[0],g,d[g]))}}return d}if(typeof a=="object")return this.each(function(){f.data(this,a)});var j=a.split(".");j[1]=j[1]?"."+j[1]:"";if(c===b){d=this.triggerHandler("getData"+j[1]+"!",[j[0]]),d===b&&this.length&&(d=f.data(this[0],a),d=k(this[0],a,d));return d===b&&j[1]?this.data(j[0]):d}return this.each(function(){var b=f(this),d=[j[0],c];b.triggerHandler("setData"+j[1]+"!",d),f.data(this,a,c),b.triggerHandler("changeData"+j[1]+"!",d)})},removeData:function(a){return this.each(function(){f.removeData(this,a)})}}),f.extend({_mark:function(a,c){a&&(c=(c||"fx")+"mark",f.data(a,c,(f.data(a,c,b,!0)||0)+1,!0))},_unmark:function(a,c,d){a!==!0&&(d=c,c=a,a=!1);if(c){d=d||"fx";var e=d+"mark",g=a?0:(f.data(c,e,b,!0)||1)-1;g?f.data(c,e,g,!0):(f.removeData(c,e,!0),m(c,d,"mark"))}},queue:function(a,c,d){if(a){c=(c||"fx")+"queue";var e=f.data(a,c,b,!0);d&&(!e||f.isArray(d)?e=f.data(a,c,f.makeArray(d),!0):e.push(d));return e||[]}},dequeue:function(a,b){b=b||"fx";var c=f.queue(a,b),d=c.shift(),e;d==="inprogress"&&(d=c.shift()),d&&(b==="fx"&&c.unshift("inprogress"),d.call(a,function(){f.dequeue(a,b)})),c.length||(f.removeData(a,b+"queue",!0),m(a,b,"queue"))}}),f.fn.extend({queue:function(a,c){typeof a!="string"&&(c=a,a="fx");if(c===b)return f.queue(this[0],a);return this.each(function(){var b=f.queue(this,a,c);a==="fx"&&b[0]!=="inprogress"&&f.dequeue(this,a)})},dequeue:function(a){return this.each(function(){f.dequeue(this,a)})},delay:function(a,b){a=f.fx?f.fx.speeds[a]||a:a,b=b||"fx";return this.queue(b,function(){var c=this;setTimeout(function(){f.dequeue(c,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,c){function m(){--h||d.resolveWith(e,[e])}typeof a!="string"&&(c=a,a=b),a=a||"fx";var d=f.Deferred(),e=this,g=e.length,h=1,i=a+"defer",j=a+"queue",k=a+"mark",l;while(g--)if(l=f.data(e[g],i,b,!0)||(f.data(e[g],j,b,!0)||f.data(e[g],k,b,!0))&&f.data(e[g],i,f._Deferred(),!0))h++,l.done(m);m();return d.promise()}});var n=/[\n\t\r]/g,o=/\s+/,p=/\r/g,q=/^(?:button|input)$/i,r=/^(?:button|input|object|select|textarea)$/i,s=/^a(?:rea)?$/i,t=/^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,u=/\:|^on/,v,w;f.fn.extend({attr:function(a,b){return f.access(this,a,b,!0,f.attr)},removeAttr:function(a){return this.each(function(){f.removeAttr(this,a)})},prop:function(a,b){return f.access(this,a,b,!0,f.prop)},removeProp:function(a){a=f.propFix[a]||a;return this.each(function(){try{this[a]=b,delete this[a]}catch(c){}})},addClass:function(a){var b,c,d,e,g,h,i;if(f.isFunction(a))return this.each(function(b){f(this).addClass(a.call(this,b,this.className))});if(a&&typeof a=="string"){b=a.split(o);for(c=0,d=this.length;c<d;c++){e=this[c];if(e.nodeType===1)if(!e.className&&b.length===1)e.className=a;else{g=" "+e.className+" ";for(h=0,i=b.length;h<i;h++)~g.indexOf(" "+b[h]+" ")||(g+=b[h]+" ");e.className=f.trim(g)}}}return this},removeClass:function(a){var c,d,e,g,h,i,j;if(f.isFunction(a))return this.each(function(b){f(this).removeClass(a.call(this,b,this.className))});if(a&&typeof a=="string"||a===b){c=(a||"").split(o);for(d=0,e=this.length;d<e;d++){g=this[d];if(g.nodeType===1&&g.className)if(a){h=(" "+g.className+" ").replace(n," ");for(i=0,j=c.length;i<j;i++)h=h.replace(" "+c[i]+" "," ");g.className=f.trim(h)}else g.className=""}}return this},toggleClass:function(a,b){var c=typeof a,d=typeof b=="boolean";if(f.isFunction(a))return this.each(function(c){f(this).toggleClass(a.call(this,c,this.className,b),b)});return this.each(function(){if(c==="string"){var e,g=0,h=f(this),i=b,j=a.split(o);while(e=j[g++])i=d?i:!h.hasClass(e),h[i?"addClass":"removeClass"](e)}else if(c==="undefined"||c==="boolean")this.className&&f._data(this,"__className__",this.className),this.className=this.className||a===!1?"":f._data(this,"__className__")||""})},hasClass:function(a){var b=" "+a+" ";for(var c=0,d=this.length;c<d;c++)if((" "+this[c].className+" ").replace(n," ").indexOf(b)>-1)return!0;return!1},val:function(a){var c,d,e=this[0];if(!arguments.length){if(e){c=f.valHooks[e.nodeName.toLowerCase()]||f.valHooks[e.type];if(c&&"get"in c&&(d=c.get(e,"value"))!==b)return d;d=e.value;return typeof d=="string"?d.replace(p,""):d==null?"":d}return b}var g=f.isFunction(a);return this.each(function(d){var e=f(this),h;if(this.nodeType===1){g?h=a.call(this,d,e.val()):h=a,h==null?h="":typeof h=="number"?h+="":f.isArray(h)&&(h=f.map(h,function(a){return a==null?"":a+""})),c=f.valHooks[this.nodeName.toLowerCase()]||f.valHooks[this.type];if(!c||!("set"in c)||c.set(this,h,"value")===b)this.value=h}})}}),f.extend({valHooks:{option:{get:function(a){var b=a.attributes.value;return!b||b.specified?a.value:a.text}},select:{get:function(a){var b,c=a.selectedIndex,d=[],e=a.options,g=a.type==="select-one";if(c<0)return null;for(var h=g?c:0,i=g?c+1:e.length;h<i;h++){var j=e[h];if(j.selected&&(f.support.optDisabled?!j.disabled:j.getAttribute("disabled")===null)&&(!j.parentNode.disabled||!f.nodeName(j.parentNode,"optgroup"))){b=f(j).val();if(g)return b;d.push(b)}}if(g&&!d.length&&e.length)return f(e[c]).val();return d},set:function(a,b){var c=f.makeArray(b);f(a).find("option").each(function(){this.selected=f.inArray(f(this).val(),c)>=0}),c.length||(a.selectedIndex=-1);return c}}},attrFn:{val:!0,css:!0,html:!0,text:!0,data:!0,width:!0,height:!0,offset:!0},attrFix:{tabindex:"tabIndex"},attr:function(a,c,d,e){var g=a.nodeType;if(!a||g===3||g===8||g===2)return b;if(e&&c in f.attrFn)return f(a)[c](d);if(!("getAttribute"in a))return f.prop(a,c,d);var h,i,j=g!==1||!f.isXMLDoc(a);j&&(c=f.attrFix[c]||c,i=f.attrHooks[c],i||(t.test(c)?i=w:v&&c!=="className"&&(f.nodeName(a,"form")||u.test(c))&&(i=v)));if(d!==b){if(d===null){f.removeAttr(a,c);return b}if(i&&"set"in i&&j&&(h=i.set(a,d,c))!==b)return h;a.setAttribute(c,""+d);return d}if(i&&"get"in i&&j&&(h=i.get(a,c))!==null)return h;h=a.getAttribute(c);return h===null?b:h},removeAttr:function(a,b){var c;a.nodeType===1&&(b=f.attrFix[b]||b,f.support.getSetAttribute?a.removeAttribute(b):(f.attr(a,b,""),a.removeAttributeNode(a.getAttributeNode(b))),t.test(b)&&(c=f.propFix[b]||b)in a&&(a[c]=!1))},attrHooks:{type:{set:function(a,b){if(q.test(a.nodeName)&&a.parentNode)f.error("type property can't be changed");else if(!f.support.radioValue&&b==="radio"&&f.nodeName(a,"input")){var c=a.value;a.setAttribute("type",b),c&&(a.value=c);return b}}},tabIndex:{get:function(a){var c=a.getAttributeNode("tabIndex");return c&&c.specified?parseInt(c.value,10):r.test(a.nodeName)||s.test(a.nodeName)&&a.href?0:b}},value:{get:function(a,b){if(v&&f.nodeName(a,"button"))return v.get(a,b);return b in a?a.value:null},set:function(a,b,c){if(v&&f.nodeName(a,"button"))return v.set(a,b,c);a.value=b}}},propFix:{tabindex:"tabIndex",readonly:"readOnly","for":"htmlFor","class":"className",maxlength:"maxLength",cellspacing:"cellSpacing",cellpadding:"cellPadding",rowspan:"rowSpan",colspan:"colSpan",usemap:"useMap",frameborder:"frameBorder",contenteditable:"contentEditable"},prop:function(a,c,d){var e=a.nodeType;if(!a||e===3||e===8||e===2)return b;var g,h,i=e!==1||!f.isXMLDoc(a);i&&(c=f.propFix[c]||c,h=f.propHooks[c]);return d!==b?h&&"set"in h&&(g=h.set(a,d,c))!==b?g:a[c]=d:h&&"get"in h&&(g=h.get(a,c))!==b?g:a[c]},propHooks:{}}),w={get:function(a,c){return f.prop(a,c)?c.toLowerCase():b},set:function(a,b,c){var d;b===!1?f.removeAttr(a,c):(d=f.propFix[c]||c,d in a&&(a[d]=!0),a.setAttribute(c,c.toLowerCase()));return c}},f.support.getSetAttribute||(f.attrFix=f.propFix,v=f.attrHooks.name=f.attrHooks.title=f.valHooks.button={get:function(a,c){var d;d=a.getAttributeNode(c);return d&&d.nodeValue!==""?d.nodeValue:b},set:function(a,b,c){var d=a.getAttributeNode(c);if(d){d.nodeValue=b;return b}}},f.each(["width","height"],function(a,b){f.attrHooks[b]=f.extend(f.attrHooks[b],{set:function(a,c){if(c===""){a.setAttribute(b,"auto");return c}}})})),f.support.hrefNormalized||f.each(["href","src","width","height"],function(a,c){f.attrHooks[c]=f.extend(f.attrHooks[c],{get:function(a){var d=a.getAttribute(c,2);return d===null?b:d}})}),f.support.style||(f.attrHooks.style={get:function(a){return a.style.cssText.toLowerCase()||b},set:function(a,b){return a.style.cssText=""+b}}),f.support.optSelected||(f.propHooks.selected=f.extend(f.propHooks.selected,{get:function(a){var b=a.parentNode;b&&(b.selectedIndex,b.parentNode&&b.parentNode.selectedIndex)}})),f.support.checkOn||f.each(["radio","checkbox"],function(){f.valHooks[this]={get:function(a){return a.getAttribute("value")===null?"on":a.value}}}),f.each(["radio","checkbox"],function(){f.valHooks[this]=f.extend(f.valHooks[this],{set:function(a,b){if(f.isArray(b))return a.checked=f.inArray(f(a).val(),b)>=0}})});var x=/\.(.*)$/,y=/^(?:textarea|input|select)$/i,z=/\./g,A=/ /g,B=/[^\w\s.|`]/g,C=function(a){return a.replace(B,"\\$&")};f.event={add:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){if(d===!1)d=D;else if(!d)return;var g,h;d.handler&&(g=d,d=g.handler),d.guid||(d.guid=f.guid++);var i=f._data(a);if(!i)return;var j=i.events,k=i.handle;j||(i.events=j={}),k||(i.handle=k=function(a){return typeof f!="undefined"&&(!a||f.event.triggered!==a.type)?f.event.handle.apply(k.elem,arguments):b}),k.elem=a,c=c.split(" ");var l,m=0,n;while(l=c[m++]){h=g?f.extend({},g):{handler:d,data:e},l.indexOf(".")>-1?(n=l.split("."),l=n.shift(),h.namespace=n.slice(0).sort().join(".")):(n=[],h.namespace=""),h.type=l,h.guid||(h.guid=d.guid);var o=j[l],p=f.event.special[l]||{};if(!o){o=j[l]=[];if(!p.setup||p.setup.call(a,e,n,k)===!1)a.addEventListener?a.addEventListener(l,k,!1):a.attachEvent&&a.attachEvent("on"+l,k)}p.add&&(p.add.call(a,h),h.handler.guid||(h.handler.guid=d.guid)),o.push(h),f.event.global[l]=!0}a=null}},global:{},remove:function(a,c,d,e){if(a.nodeType!==3&&a.nodeType!==8){d===!1&&(d=D);var g,h,i,j,k=0,l,m,n,o,p,q,r,s=f.hasData(a)&&f._data(a),t=s&&s.events;if(!s||!t)return;c&&c.type&&(d=c.handler,c=c.type);if(!c||typeof c=="string"&&c.charAt(0)==="."){c=c||"";for(h in t)f.event.remove(a,h+c);return}c=c.split(" ");while(h=c[k++]){r=h,q=null,l=h.indexOf(".")<0,m=[],l||(m=h.split("."),h=m.shift(),n=new RegExp("(^|\\.)"+f.map(m.slice(0).sort(),C).join("\\.(?:.*\\.)?")+"(\\.|$)")),p=t[h];if(!p)continue;if(!d){for(j=0;j<p.length;j++){q=p[j];if(l||n.test(q.namespace))f.event.remove(a,r,q.handler,j),p.splice(j--,1)}continue}o=f.event.special[h]||{};for(j=e||0;j<p.length;j++){q=p[j];if(d.guid===q.guid){if(l||n.test(q.namespace))e==null&&p.splice(j--,1),o.remove&&o.remove.call(a,q);if(e!=null)break}}if(p.length===0||e!=null&&p.length===1)(!o.teardown||o.teardown.call(a,m)===!1)&&f.removeEvent(a,h,s.handle),g=null,delete t[h]}if(f.isEmptyObject(t)){var u=s.handle;u&&(u.elem=null),delete s.events,delete s.handle,f.isEmptyObject(s)&&f.removeData(a,b,!0)}}},customEvent:{getData:!0,setData:!0,changeData:!0},trigger:function(c,d,e,g){var h=c.type||c,i=[],j;h.indexOf("!")>=0&&(h=h.slice(0,-1),j=!0),h.indexOf(".")>=0&&(i=h.split("."),h=i.
-shift(),i.sort());if(!!e&&!f.event.customEvent[h]||!!f.event.global[h]){c=typeof c=="object"?c[f.expando]?c:new f.Event(h,c):new f.Event(h),c.type=h,c.exclusive=j,c.namespace=i.join("."),c.namespace_re=new RegExp("(^|\\.)"+i.join("\\.(?:.*\\.)?")+"(\\.|$)");if(g||!e)c.preventDefault(),c.stopPropagation();if(!e){f.each(f.cache,function(){var a=f.expando,b=this[a];b&&b.events&&b.events[h]&&f.event.trigger(c,d,b.handle.elem)});return}if(e.nodeType===3||e.nodeType===8)return;c.result=b,c.target=e,d=d!=null?f.makeArray(d):[],d.unshift(c);var k=e,l=h.indexOf(":")<0?"on"+h:"";do{var m=f._data(k,"handle");c.currentTarget=k,m&&m.apply(k,d),l&&f.acceptData(k)&&k[l]&&k[l].apply(k,d)===!1&&(c.result=!1,c.preventDefault()),k=k.parentNode||k.ownerDocument||k===c.target.ownerDocument&&a}while(k&&!c.isPropagationStopped());if(!c.isDefaultPrevented()){var n,o=f.event.special[h]||{};if((!o._default||o._default.call(e.ownerDocument,c)===!1)&&(h!=="click"||!f.nodeName(e,"a"))&&f.acceptData(e)){try{l&&e[h]&&(n=e[l],n&&(e[l]=null),f.event.triggered=h,e[h]())}catch(p){}n&&(e[l]=n),f.event.triggered=b}}return c.result}},handle:function(c){c=f.event.fix(c||a.event);var d=((f._data(this,"events")||{})[c.type]||[]).slice(0),e=!c.exclusive&&!c.namespace,g=Array.prototype.slice.call(arguments,0);g[0]=c,c.currentTarget=this;for(var h=0,i=d.length;h<i;h++){var j=d[h];if(e||c.namespace_re.test(j.namespace)){c.handler=j.handler,c.data=j.data,c.handleObj=j;var k=j.handler.apply(this,g);k!==b&&(c.result=k,k===!1&&(c.preventDefault(),c.stopPropagation()));if(c.isImmediatePropagationStopped())break}}return c.result},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode layerX layerY metaKey newValue offsetX offsetY pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(a){if(a[f.expando])return a;var d=a;a=f.Event(d);for(var e=this.props.length,g;e;)g=this.props[--e],a[g]=d[g];a.target||(a.target=a.srcElement||c),a.target.nodeType===3&&(a.target=a.target.parentNode),!a.relatedTarget&&a.fromElement&&(a.relatedTarget=a.fromElement===a.target?a.toElement:a.fromElement);if(a.pageX==null&&a.clientX!=null){var h=a.target.ownerDocument||c,i=h.documentElement,j=h.body;a.pageX=a.clientX+(i&&i.scrollLeft||j&&j.scrollLeft||0)-(i&&i.clientLeft||j&&j.clientLeft||0),a.pageY=a.clientY+(i&&i.scrollTop||j&&j.scrollTop||0)-(i&&i.clientTop||j&&j.clientTop||0)}a.which==null&&(a.charCode!=null||a.keyCode!=null)&&(a.which=a.charCode!=null?a.charCode:a.keyCode),!a.metaKey&&a.ctrlKey&&(a.metaKey=a.ctrlKey),!a.which&&a.button!==b&&(a.which=a.button&1?1:a.button&2?3:a.button&4?2:0);return a},guid:1e8,proxy:f.proxy,special:{ready:{setup:f.bindReady,teardown:f.noop},live:{add:function(a){f.event.add(this,N(a.origType,a.selector),f.extend({},a,{handler:M,guid:a.handler.guid}))},remove:function(a){f.event.remove(this,N(a.origType,a.selector),a)}},beforeunload:{setup:function(a,b,c){f.isWindow(this)&&(this.onbeforeunload=c)},teardown:function(a,b){this.onbeforeunload===b&&(this.onbeforeunload=null)}}}},f.removeEvent=c.removeEventListener?function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c,!1)}:function(a,b,c){a.detachEvent&&a.detachEvent("on"+b,c)},f.Event=function(a,b){if(!this.preventDefault)return new f.Event(a,b);a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||a.returnValue===!1||a.getPreventDefault&&a.getPreventDefault()?E:D):this.type=a,b&&f.extend(this,b),this.timeStamp=f.now(),this[f.expando]=!0},f.Event.prototype={preventDefault:function(){this.isDefaultPrevented=E;var a=this.originalEvent;!a||(a.preventDefault?a.preventDefault():a.returnValue=!1)},stopPropagation:function(){this.isPropagationStopped=E;var a=this.originalEvent;!a||(a.stopPropagation&&a.stopPropagation(),a.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=E,this.stopPropagation()},isDefaultPrevented:D,isPropagationStopped:D,isImmediatePropagationStopped:D};var F=function(a){var b=a.relatedTarget,c=!1,d=a.type;a.type=a.data,b!==this&&(b&&(c=f.contains(this,b)),c||(f.event.handle.apply(this,arguments),a.type=d))},G=function(a){a.type=a.data,f.event.handle.apply(this,arguments)};f.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(a,b){f.event.special[a]={setup:function(c){f.event.add(this,b,c&&c.selector?G:F,a)},teardown:function(a){f.event.remove(this,b,a&&a.selector?G:F)}}}),f.support.submitBubbles||(f.event.special.submit={setup:function(a,b){if(!f.nodeName(this,"form"))f.event.add(this,"click.specialSubmit",function(a){var b=a.target,c=b.type;(c==="submit"||c==="image")&&f(b).closest("form").length&&K("submit",this,arguments)}),f.event.add(this,"keypress.specialSubmit",function(a){var b=a.target,c=b.type;(c==="text"||c==="password")&&f(b).closest("form").length&&a.keyCode===13&&K("submit",this,arguments)});else return!1},teardown:function(a){f.event.remove(this,".specialSubmit")}});if(!f.support.changeBubbles){var H,I=function(a){var b=a.type,c=a.value;b==="radio"||b==="checkbox"?c=a.checked:b==="select-multiple"?c=a.selectedIndex>-1?f.map(a.options,function(a){return a.selected}).join("-"):"":f.nodeName(a,"select")&&(c=a.selectedIndex);return c},J=function(c){var d=c.target,e,g;if(!!y.test(d.nodeName)&&!d.readOnly){e=f._data(d,"_change_data"),g=I(d),(c.type!=="focusout"||d.type!=="radio")&&f._data(d,"_change_data",g);if(e===b||g===e)return;if(e!=null||g)c.type="change",c.liveFired=b,f.event.trigger(c,arguments[1],d)}};f.event.special.change={filters:{focusout:J,beforedeactivate:J,click:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(c==="radio"||c==="checkbox"||f.nodeName(b,"select"))&&J.call(this,a)},keydown:function(a){var b=a.target,c=f.nodeName(b,"input")?b.type:"";(a.keyCode===13&&!f.nodeName(b,"textarea")||a.keyCode===32&&(c==="checkbox"||c==="radio")||c==="select-multiple")&&J.call(this,a)},beforeactivate:function(a){var b=a.target;f._data(b,"_change_data",I(b))}},setup:function(a,b){if(this.type==="file")return!1;for(var c in H)f.event.add(this,c+".specialChange",H[c]);return y.test(this.nodeName)},teardown:function(a){f.event.remove(this,".specialChange");return y.test(this.nodeName)}},H=f.event.special.change.filters,H.focus=H.beforeactivate}f.support.focusinBubbles||f.each({focus:"focusin",blur:"focusout"},function(a,b){function e(a){var c=f.event.fix(a);c.type=b,c.originalEvent={},f.event.trigger(c,null,c.target),c.isDefaultPrevented()&&a.preventDefault()}var d=0;f.event.special[b]={setup:function(){d++===0&&c.addEventListener(a,e,!0)},teardown:function(){--d===0&&c.removeEventListener(a,e,!0)}}}),f.each(["bind","one"],function(a,c){f.fn[c]=function(a,d,e){var g;if(typeof a=="object"){for(var h in a)this[c](h,d,a[h],e);return this}if(arguments.length===2||d===!1)e=d,d=b;c==="one"?(g=function(a){f(this).unbind(a,g);return e.apply(this,arguments)},g.guid=e.guid||f.guid++):g=e;if(a==="unload"&&c!=="one")this.one(a,d,e);else for(var i=0,j=this.length;i<j;i++)f.event.add(this[i],a,g,d);return this}}),f.fn.extend({unbind:function(a,b){if(typeof a=="object"&&!a.preventDefault)for(var c in a)this.unbind(c,a[c]);else for(var d=0,e=this.length;d<e;d++)f.event.remove(this[d],a,b);return this},delegate:function(a,b,c,d){return this.live(b,c,d,a)},undelegate:function(a,b,c){return arguments.length===0?this.unbind("live"):this.die(b,null,c,a)},trigger:function(a,b){return this.each(function(){f.event.trigger(a,b,this)})},triggerHandler:function(a,b){if(this[0])return f.event.trigger(a,b,this[0],!0)},toggle:function(a){var b=arguments,c=a.guid||f.guid++,d=0,e=function(c){var e=(f.data(this,"lastToggle"+a.guid)||0)%d;f.data(this,"lastToggle"+a.guid,e+1),c.preventDefault();return b[e].apply(this,arguments)||!1};e.guid=c;while(d<b.length)b[d++].guid=c;return this.click(e)},hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}});var L={focus:"focusin",blur:"focusout",mouseenter:"mouseover",mouseleave:"mouseout"};f.each(["live","die"],function(a,c){f.fn[c]=function(a,d,e,g){var h,i=0,j,k,l,m=g||this.selector,n=g?this:f(this.context);if(typeof a=="object"&&!a.preventDefault){for(var o in a)n[c](o,d,a[o],m);return this}if(c==="die"&&!a&&g&&g.charAt(0)==="."){n.unbind(g);return this}if(d===!1||f.isFunction(d))e=d||D,d=b;a=(a||"").split(" ");while((h=a[i++])!=null){j=x.exec(h),k="",j&&(k=j[0],h=h.replace(x,""));if(h==="hover"){a.push("mouseenter"+k,"mouseleave"+k);continue}l=h,L[h]?(a.push(L[h]+k),h=h+k):h=(L[h]||h)+k;if(c==="live")for(var p=0,q=n.length;p<q;p++)f.event.add(n[p],"live."+N(h,m),{data:d,selector:m,handler:e,origType:h,origHandler:e,preType:l});else n.unbind("live."+N(h,m),e)}return this}}),f.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error".split(" "),function(a,b){f.fn[b]=function(a,c){c==null&&(c=a,a=null);return arguments.length>0?this.bind(b,a,c):this.trigger(b)},f.attrFn&&(f.attrFn[b]=!0)}),function(){function u(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}if(i.nodeType===1){f||(i.sizcache=c,i.sizset=g);if(typeof b!="string"){if(i===b){j=!0;break}}else if(k.filter(b,[i]).length>0){j=i;break}}i=i[a]}d[g]=j}}}function t(a,b,c,d,e,f){for(var g=0,h=d.length;g<h;g++){var i=d[g];if(i){var j=!1;i=i[a];while(i){if(i.sizcache===c){j=d[i.sizset];break}i.nodeType===1&&!f&&(i.sizcache=c,i.sizset=g);if(i.nodeName.toLowerCase()===b){j=i;break}i=i[a]}d[g]=j}}}var a=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^\[\]]*\]|['"][^'"]*['"]|[^\[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,d=0,e=Object.prototype.toString,g=!1,h=!0,i=/\\/g,j=/\W/;[0,0].sort(function(){h=!1;return 0});var k=function(b,d,f,g){f=f||[],d=d||c;var h=d;if(d.nodeType!==1&&d.nodeType!==9)return[];if(!b||typeof b!="string")return f;var i,j,n,o,q,r,s,t,u=!0,w=k.isXML(d),x=[],y=b;do{a.exec(""),i=a.exec(y);if(i){y=i[3],x.push(i[1]);if(i[2]){o=i[3];break}}}while(i);if(x.length>1&&m.exec(b))if(x.length===2&&l.relative[x[0]])j=v(x[0]+x[1],d);else{j=l.relative[x[0]]?[d]:k(x.shift(),d);while(x.length)b=x.shift(),l.relative[b]&&(b+=x.shift()),j=v(b,j)}else{!g&&x.length>1&&d.nodeType===9&&!w&&l.match.ID.test(x[0])&&!l.match.ID.test(x[x.length-1])&&(q=k.find(x.shift(),d,w),d=q.expr?k.filter(q.expr,q.set)[0]:q.set[0]);if(d){q=g?{expr:x.pop(),set:p(g)}:k.find(x.pop(),x.length===1&&(x[0]==="~"||x[0]==="+")&&d.parentNode?d.parentNode:d,w),j=q.expr?k.filter(q.expr,q.set):q.set,x.length>0?n=p(j):u=!1;while(x.length)r=x.pop(),s=r,l.relative[r]?s=x.pop():r="",s==null&&(s=d),l.relative[r](n,s,w)}else n=x=[]}n||(n=j),n||k.error(r||b);if(e.call(n)==="[object Array]")if(!u)f.push.apply(f,n);else if(d&&d.nodeType===1)for(t=0;n[t]!=null;t++)n[t]&&(n[t]===!0||n[t].nodeType===1&&k.contains(d,n[t]))&&f.push(j[t]);else for(t=0;n[t]!=null;t++)n[t]&&n[t].nodeType===1&&f.push(j[t]);else p(n,f);o&&(k(o,h,f,g),k.uniqueSort(f));return f};k.uniqueSort=function(a){if(r){g=h,a.sort(r);if(g)for(var b=1;b<a.length;b++)a[b]===a[b-1]&&a.splice(b--,1)}return a},k.matches=function(a,b){return k(a,null,null,b)},k.matchesSelector=function(a,b){return k(b,null,null,[a]).length>0},k.find=function(a,b,c){var d;if(!a)return[];for(var e=0,f=l.order.length;e<f;e++){var g,h=l.order[e];if(g=l.leftMatch[h].exec(a)){var j=g[1];g.splice(1,1);if(j.substr(j.length-1)!=="\\"){g[1]=(g[1]||"").replace(i,""),d=l.find[h](g,b,c);if(d!=null){a=a.replace(l.match[h],"");break}}}}d||(d=typeof b.getElementsByTagName!="undefined"?b.getElementsByTagName("*"):[]);return{set:d,expr:a}},k.filter=function(a,c,d,e){var f,g,h=a,i=[],j=c,m=c&&c[0]&&k.isXML(c[0]);while(a&&c.length){for(var n in l.filter)if((f=l.leftMatch[n].exec(a))!=null&&f[2]){var o,p,q=l.filter[n],r=f[1];g=!1,f.splice(1,1);if(r.substr(r.length-1)==="\\")continue;j===i&&(i=[]);if(l.preFilter[n]){f=l.preFilter[n](f,j,d,i,e,m);if(!f)g=o=!0;else if(f===!0)continue}if(f)for(var s=0;(p=j[s])!=null;s++)if(p){o=q(p,f,s,j);var t=e^!!o;d&&o!=null?t?g=!0:j[s]=!1:t&&(i.push(p),g=!0)}if(o!==b){d||(j=i),a=a.replace(l.match[n],"");if(!g)return[];break}}if(a===h)if(g==null)k.error(a);else break;h=a}return j},k.error=function(a){throw"Syntax error, unrecognized expression: "+a};var l=k.selectors={order:["ID","NAME","TAG"],match:{ID:/#((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,CLASS:/\.((?:[\w\u00c0-\uFFFF\-]|\\.)+)/,NAME:/\[name=['"]*((?:[\w\u00c0-\uFFFF\-]|\\.)+)['"]*\]/,ATTR:/\[\s*((?:[\w\u00c0-\uFFFF\-]|\\.)+)\s*(?:(\S?=)\s*(?:(['"])(.*?)\3|(#?(?:[\w\u00c0-\uFFFF\-]|\\.)*)|)|)\s*\]/,TAG:/^((?:[\w\u00c0-\uFFFF\*\-]|\\.)+)/,CHILD:/:(only|nth|last|first)-child(?:\(\s*(even|odd|(?:[+\-]?\d+|(?:[+\-]?\d*)?n\s*(?:[+\-]\s*\d+)?))\s*\))?/,POS:/:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^\-]|$)/,PSEUDO:/:((?:[\w\u00c0-\uFFFF\-]|\\.)+)(?:\((['"]?)((?:\([^\)]+\)|[^\(\)]*)+)\2\))?/},leftMatch:{},attrMap:{"class":"className","for":"htmlFor"},attrHandle:{href:function(a){return a.getAttribute("href")},type:function(a){return a.getAttribute("type")}},relative:{"+":function(a,b){var c=typeof b=="string",d=c&&!j.test(b),e=c&&!d;d&&(b=b.toLowerCase());for(var f=0,g=a.length,h;f<g;f++)if(h=a[f]){while((h=h.previousSibling)&&h.nodeType!==1);a[f]=e||h&&h.nodeName.toLowerCase()===b?h||!1:h===b}e&&k.filter(b,a,!0)},">":function(a,b){var c,d=typeof b=="string",e=0,f=a.length;if(d&&!j.test(b)){b=b.toLowerCase();for(;e<f;e++){c=a[e];if(c){var g=c.parentNode;a[e]=g.nodeName.toLowerCase()===b?g:!1}}}else{for(;e<f;e++)c=a[e],c&&(a[e]=d?c.parentNode:c.parentNode===b);d&&k.filter(b,a,!0)}},"":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("parentNode",b,f,a,e,c)},"~":function(a,b,c){var e,f=d++,g=u;typeof b=="string"&&!j.test(b)&&(b=b.toLowerCase(),e=b,g=t),g("previousSibling",b,f,a,e,c)}},find:{ID:function(a,b,c){if(typeof b.getElementById!="undefined"&&!c){var d=b.getElementById(a[1]);return d&&d.parentNode?[d]:[]}},NAME:function(a,b){if(typeof b.getElementsByName!="undefined"){var c=[],d=b.getElementsByName(a[1]);for(var e=0,f=d.length;e<f;e++)d[e].getAttribute("name")===a[1]&&c.push(d[e]);return c.length===0?null:c}},TAG:function(a,b){if(typeof b.getElementsByTagName!="undefined")return b.getElementsByTagName(a[1])}},preFilter:{CLASS:function(a,b,c,d,e,f){a=" "+a[1].replace(i,"")+" ";if(f)return a;for(var g=0,h;(h=b[g])!=null;g++)h&&(e^(h.className&&(" "+h.className+" ").replace(/[\t\n\r]/g," ").indexOf(a)>=0)?c||d.push(h):c&&(b[g]=!1));return!1},ID:function(a){return a[1].replace(i,"")},TAG:function(a,b){return a[1].replace(i,"").toLowerCase()},CHILD:function(a){if(a[1]==="nth"){a[2]||k.error(a[0]),a[2]=a[2].replace(/^\+|\s*/g,"");var b=/(-?)(\d*)(?:n([+\-]?\d*))?/.exec(a[2]==="even"&&"2n"||a[2]==="odd"&&"2n+1"||!/\D/.test(a[2])&&"0n+"+a[2]||a[2]);a[2]=b[1]+(b[2]||1)-0,a[3]=b[3]-0}else a[2]&&k.error(a[0]);a[0]=d++;return a},ATTR:function(a,b,c,d,e,f){var g=a[1]=a[1].replace(i,"");!f&&l.attrMap[g]&&(a[1]=l.attrMap[g]),a[4]=(a[4]||a[5]||"").replace(i,""),a[2]==="~="&&(a[4]=" "+a[4]+" ");return a},PSEUDO:function(b,c,d,e,f){if(b[1]==="not")if((a.exec(b[3])||"").length>1||/^\w/.test(b[3]))b[3]=k(b[3],null,null,c);else{var g=k.filter(b[3],c,d,!0^f);d||e.push.apply(e,g);return!1}else if(l.match.POS.test(b[0])||l.match.CHILD.test(b[0]))return!0;return b},POS:function(a){a.unshift(!0);return a}},filters:{enabled:function(a){return a.disabled===!1&&a.type!=="hidden"},disabled:function(a){return a.disabled===!0},checked:function(a){return a.checked===!0},selected:function(a){a.parentNode&&a.parentNode.selectedIndex;return a.selected===!0},parent:function(a){return!!a.firstChild},empty:function(a){return!a.firstChild},has:function(a,b,c){return!!k(c[3],a).length},header:function(a){return/h\d/i.test(a.nodeName)},text:function(a){var b=a.getAttribute("type"),c=a.type;return a.nodeName.toLowerCase()==="input"&&"text"===c&&(b===c||b===null)},radio:function(a){return a.nodeName.toLowerCase()==="input"&&"radio"===a.type},checkbox:function(a){return a.nodeName.toLowerCase()==="input"&&"checkbox"===a.type},file:function(a){return a.nodeName.toLowerCase()==="input"&&"file"===a.type},password:function(a){return a.nodeName.toLowerCase()==="input"&&"password"===a.type},submit:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"submit"===a.type},image:function(a){return a.nodeName.toLowerCase()==="input"&&"image"===a.type},reset:function(a){var b=a.nodeName.toLowerCase();return(b==="input"||b==="button")&&"reset"===a.type},button:function(a){var b=a.nodeName.toLowerCase();return b==="input"&&"button"===a.type||b==="button"},input:function(a){return/input|select|textarea|button/i.test(a.nodeName)},focus:function(a){return a===a.ownerDocument.activeElement}},setFilters:{first:function(a,b){return b===0},last:function(a,b,c,d){return b===d.length-1},even:function(a,b){return b%2===0},odd:function(a,b){return b%2===1},lt:function(a,b,c){return b<c[3]-0},gt:function(a,b,c){return b>c[3]-0},nth:function(a,b,c){return c[3]-0===b},eq:function(a,b,c){return c[3]-0===b}},filter:{PSEUDO:function(a,b,c,d){var e=b[1],f=l.filters[e];if(f)return f(a,c,b,d);if(e==="contains")return(a.textContent||a.innerText||k.getText([a])||"").indexOf(b[3])>=0;if(e==="not"){var g=b[3];for(var h=0,i=g.length;h<i;h++)if(g[h]===a)return!1;return!0}k.error(e)},CHILD:function(a,b){var c=b[1],d=a;switch(c){case"only":case"first":while(d=d.previousSibling)if(d.nodeType===1)return!1;if(c==="first")return!0;d=a;case"last":while(d=d.nextSibling)if(d.nodeType===1)return!1;return!0;case"nth":var e=b[2],f=b[3];if(e===1&&f===0)return!0;var g=b[0],h=a.parentNode;if(h&&(h.sizcache!==g||!a.nodeIndex)){var i=0;for(d=h.firstChild;d;d=d.nextSibling)d.nodeType===1&&(d.nodeIndex=++i);h.sizcache=g}var j=a.nodeIndex-f;return e===0?j===0:j%e===0&&j/e>=0}},ID:function(a,b){return a.nodeType===1&&a.getAttribute("id")===b},TAG:function(a,b){return b==="*"&&a.nodeType===1||a.nodeName.toLowerCase()===b},CLASS:function(a,b){return(" "+(a.className||a.getAttribute("class"))+" ").indexOf(b)>-1},ATTR:function(a,b){var c=b[1],d=l.attrHandle[c]?l.attrHandle[c](a):a[c]!=null?a[c]:a.getAttribute(c),e=d+"",f=b[2],g=b[4];return d==null?f==="!=":f==="="?e===g:f==="*="?e.indexOf(g)>=0:f==="~="?(" "+e+" ").indexOf(g)>=0:g?f==="!="?e!==g:f==="^="?e.indexOf(g)===0:f==="$="?e.substr(e.length-g.length)===g:f==="|="?e===g||e.substr(0,g.length+1)===g+"-":!1:e&&d!==!1},POS:function(a,b,c,d){var e=b[2],f=l.setFilters[e];if(f)return f(a,c,b,d)}}},m=l.match.POS,n=function(a,b){return"\\"+(b-0+1)};for(var o in l.match)l.match[o]=new RegExp(l.match[o].source+/(?![^\[]*\])(?![^\(]*\))/.source),l.leftMatch[o]=new RegExp(/(^(?:.|\r|\n)*?)/.source+l.match[o].source.replace(/\\(\d+)/g,n));var p=function(a,b){a=Array.prototype.slice.call(a,0);if(b){b.push.apply(b,a);return b}return a};try{Array.prototype.slice.call(c.documentElement.childNodes,0)[0].nodeType}catch(q){p=function(a,b){var c=0,d=b||[];if(e.call(a)==="[object Array]")Array.prototype.push.apply(d,a);else if(typeof a.length=="number")for(var f=a.length;c<f;c++)d.push(a[c]);else for(;a[c];c++)d.push(a[c]);return d}}var r,s;c.documentElement.compareDocumentPosition?r=function(a,b){if(a===b){g=!0;return 0}if(!a.compareDocumentPosition||!b.compareDocumentPosition)return a.compareDocumentPosition?-1:1;return a.compareDocumentPosition(b)&4?-1:1}:(r=function(a,b){if(a===b){g=!0;return 0}if(a.sourceIndex&&b.sourceIndex)return a.sourceIndex-b.sourceIndex;var c,d,e=[],f=[],h=a.parentNode,i=b.parentNode,j=h;if(h===i)return s(a,b);if(!h)return-1;if(!i)return 1;while(j)e.unshift(j),j=j.parentNode;j=i;while(j)f.unshift(j),j=j.parentNode;c=e.length,d=f.length;for(var k=0;k<c&&k<d;k++)if(e[k]!==f[k])return s(e[k],f[k]);return k===c?s(a,f[k],-1):s(e[k],b,1)},s=function(a,b,c){if(a===b)return c;var d=a.nextSibling;while(d){if(d===b)return-1;d=d.nextSibling}return 1}),k.getText=function(a){var b="",c;for(var d=0;a[d];d++)c=a[d],c.nodeType===3||c.nodeType===4?b+=c.nodeValue:c.nodeType!==8&&(b+=k.getText(c.childNodes));return b},function(){var a=c.createElement("div"),d="script"+(new Date).getTime(),e=c.documentElement;a.innerHTML="<a name='"+d+"'/>",e.insertBefore(a,e.firstChild),c.getElementById(d)&&(l.find.ID=function(a,c,d){if(typeof c.getElementById!="undefined"&&!d){var e=c.getElementById(a[1]);return e?e.id===a[1]||typeof e.getAttributeNode!="undefined"&&e.getAttributeNode("id").nodeValue===a[1]?[e]:b:[]}},l.filter.ID=function(a,b){var c=typeof a.getAttributeNode!="undefined"&&a.getAttributeNode("id");return a.nodeType===1&&c&&c.nodeValue===b}),e.removeChild(a),e=a=null}(),function(){var a=c.createElement("div");a.appendChild(c.createComment("")),a.getElementsByTagName("*").length>0&&(l.find.TAG=function(a,b){var c=b.getElementsByTagName(a[1]);if(a[1]==="*"){var d=[];for(var e=0;c[e];e++)c[e].nodeType===1&&d.push(c[e]);c=d}return c}),a.innerHTML="<a href='#'></a>",a.firstChild&&typeof a.firstChild.getAttribute!="undefined"&&a.firstChild.getAttribute("href")!=="#"&&(l.attrHandle.href=function(a){return a.getAttribute("href",2)}),a=null}(),c.querySelectorAll&&function(){var a=k,b=c.createElement("div"),d="__sizzle__";b.innerHTML="<p class='TEST'></p>";if(!b.querySelectorAll||b.querySelectorAll(".TEST").length!==0){k=function(b,e,f,g){e=e||c;if(!g&&!k.isXML(e)){var h=/^(\w+$)|^\.([\w\-]+$)|^#([\w\-]+$)/.exec(b);if(h&&(e.nodeType===1||e.nodeType===9)){if(h[1])return p(e.getElementsByTagName(b),f);if(h[2]&&l.find.CLASS&&e.getElementsByClassName)return p(e.getElementsByClassName(h[2]),f)}if(e.nodeType===9){if(b==="body"&&e.body)return p([e.body],f);if(h&&h[3]){var i=e.getElementById(h[3]);if(!i||!i.parentNode)return p([],f);if(i.id===h[3])return p([i],f)}try{return p(e.querySelectorAll(b),f)}catch(j){}}else if(e.nodeType===1&&e.nodeName.toLowerCase()!=="object"){var m=e,n=e.getAttribute("id"),o=n||d,q=e.parentNode,r=/^\s*[+~]/.test(b);n?o=o.replace(/'/g,"\\$&"):e.setAttribute("id",o),r&&q&&(e=e.parentNode);try{if(!r||q)return p(e.querySelectorAll("[id='"+o+"'] "+b),f)}catch(s){}finally{n||m.removeAttribute("id")}}}return a(b,e,f,g)};for(var e in a)k[e]=a[e];b=null}}(),function(){var a=c.documentElement,b=a.matchesSelector||a.mozMatchesSelector||a.webkitMatchesSelector||a.msMatchesSelector;if(b){var d=!b.call(c.createElement("div"),"div"),e=!1;try{b.call(c.documentElement,"[test!='']:sizzle")}catch(f){e=!0}k.matchesSelector=function(a,c){c=c.replace(/\=\s*([^'"\]]*)\s*\]/g,"='$1']");if(!k.isXML(a))try{if(e||!l.match.PSEUDO.test(c)&&!/!=/.test(c)){var f=b.call(a,c);if(f||!d||a.document&&a.document.nodeType!==11)return f}}catch(g){}return k(c,null,null,[a]).length>0}}}(),function(){var a=c.createElement("div");a.innerHTML="<div class='test e'></div><div class='test'></div>";if(!!a.getElementsByClassName&&a.getElementsByClassName("e").length!==0){a.lastChild.className="e";if(a.getElementsByClassName("e").length===1)return;l.order.splice(1,0,"CLASS"),l.find.CLASS=function(a,b,c){if(typeof b.getElementsByClassName!="undefined"&&!c)return b.getElementsByClassName(a[1])},a=null}}(),c.documentElement.contains?k.contains=function(a,b){return a!==b&&(a.contains?a.contains(b):!0)}:c.documentElement.compareDocumentPosition?k.contains=function(a,b){return!!(a.compareDocumentPosition(b)&16)}:k.contains=function(){return!1},k.isXML=function(a){var b=(a?a.ownerDocument||a:0).documentElement;return b?b.nodeName!=="HTML":!1};var v=function(a,b){var c,d=[],e="",f=b.nodeType?[b]:b;while(c=l.match.PSEUDO.exec(a))e+=c[0],a=a.replace(l.match.PSEUDO,"");a=l.relative[a]?a+"*":a;for(var g=0,h=f.length;g<h;g++)k(a,f[g],d);return k.filter(e,d)};f.find=k,f.expr=k.selectors,f.expr[":"]=f.expr.filters,f.unique=k.uniqueSort,f.text=k.getText,f.isXMLDoc=k.isXML,f.contains=k.contains}();var O=/Until$/,P=/^(?:parents|prevUntil|prevAll)/,Q=/,/,R=/^.[^:#\[\.,]*$/,S=Array.prototype.slice,T=f.expr.match.POS,U={children:!0,contents:!0,next:!0,prev:!0};f.fn.extend({find:function(a){var b=this,c,d;if(typeof a!="string")return f(a).filter(function(){for(c=0,d=b.length;c<d;c++)if(f.contains(b[c],this))return!0});var e=this.pushStack("","find",a),g,h,i;for(c=0,d=this.length;c<d;c++){g=e.length,f.find(a,this[c],e);if(c>0)for(h=g;h<e.length;h++)for(i=0;i<g;i++)if(e[i]===e[h]){e.splice(h--,1);break}}return e},has:function(a){var b=f(a);return this.filter(function(){for(var a=0,c=b.length;a<c;a++)if(f.contains(this,b[a]))return!0})},not:function(a){return this.pushStack(W(this,a,!1),"not",a)},filter:function(a){return this.pushStack(W(this,a,!0),"filter",a)},is:function(a){return!!a&&(typeof a=="string"?f.filter(a,this).length>0:this.filter(a).length>0)},closest:function(a,b){var c=[],d,e,g=this[0];if(f.isArray(a)){var h,i,j={},k=1;if(g&&a.length){for(d=0,e=a.length;d<e;d++)i=a[d],j[i]||(j[i]=T.test(i)?f(i,b||this.context):i);while(g&&g.ownerDocument&&g!==b){for(i in j)h=j[i],(h.jquery?h.index(g)>-1:f(g).is(h))&&c.push({selector:i,elem:g,level:k});g=g.parentNode,k++}}return c}var l=T.test(a)||typeof a!="string"?f(a,b||this.context):0;for(d=0,e=this.length;d<e;d++){g=this[d];while(g){if(l?l.index(g)>-1:f.find.matchesSelector(g,a)){c.push(g);break}g=g.parentNode;if(!g||!g.ownerDocument||g===b||g.nodeType===11)break}}c=c.length>1?f.unique(c):c;return this.pushStack(c,"closest",a)},index:function(a){if(!a||typeof a=="string")return f.inArray(this[0],a?f(a):this.parent().children());return f.inArray(a.jquery?a[0]:a,this)},add:function(a,b){var c=typeof a=="string"?f(a,b):f.makeArray(a&&a.nodeType?[a]:a),d=f.merge(this.get(),c);return this.pushStack(V(c[0])||V(d[0])?d:f.unique(d))},andSelf:function(){return this.add(this.prevObject)}}),f.each({parent:function(a){var b=a.parentNode;return b&&b.nodeType!==11?b:null},parents:function(a){return f.dir(a,"parentNode")},parentsUntil:function(a,b,c){return f.dir(a,"parentNode",c)},next:function(a){return f.nth(a,2,"nextSibling")},prev:function(a){return f.nth(a,2,"previousSibling")},nextAll:function(a){return f.dir(a,"nextSibling")},prevAll:function(a){return f.dir(a,"previousSibling")},nextUntil:function(a,b,c){return f.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return f.dir(a,"previousSibling",c)},siblings:function(a){return f.sibling(a.parentNode.firstChild,a)},children:function(a){return f.sibling(a.firstChild)},contents:function(a){return f.nodeName(a,"iframe")?a.contentDocument||a.contentWindow.document:f.makeArray(a.childNodes)}},function(a,b){f.fn[a]=function(c,d){var e=f.map(this,b,c),g=S.call(arguments);O.test(a)||(d=c),d&&typeof d=="string"&&(e=f.filter(d,e)),e=this.length>1&&!U[a]?f.unique(e):e,(this.length>1||Q.test(d))&&P.test(a)&&(e=e.reverse());return this.pushStack(e,a,g.join(","))}}),f.extend({filter:function(a,b,c){c&&(a=":not("+a+")");return b.length===1?f.find.matchesSelector(b[0],a)?[b[0]]:[]:f.find.matches(a,b)},dir:function(a,c,d){var e=[],g=a[c];while(g&&g.nodeType!==9&&(d===b||g.nodeType!==1||!f(g).is(d)))g.nodeType===1&&e.push(g),g=g[c];return e},nth:function(a,b,c,d){b=b||1;var e=0;for(;a;a=a[c])if(a.nodeType===1&&++e===b)break;return a},sibling:function(a,b){var c=[];for(;a;a=a.nextSibling)a.nodeType===1&&a!==b&&c.push(a);return c}});var X=/ jQuery\d+="(?:\d+|null)"/g,Y=/^\s+/,Z=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/ig,$=/<([\w:]+)/,_=/<tbody/i,ba=/<|&#?\w+;/,bb=/<(?:script|object|embed|option|style)/i,bc=/checked\s*(?:[^=]|=\s*.checked.)/i,bd=/\/(java|ecma)script/i,be=/^\s*<!(?:\[CDATA\[|\-\-)/,bf={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],area:[1,"<map>","</map>"],_default:[0,"",""]};bf.optgroup=bf.option,bf.tbody=bf.tfoot=bf.colgroup=bf.caption=bf.thead,bf.th=bf.td,f.support.htmlSerialize||(bf._default=[1,"div<div>","</div>"]),f.fn.extend({text:function(a){if(f.isFunction(a))return this.each(function(b){var c=f(this);c.text(a.call(this,b,c.text()))});if(typeof a!="object"&&a!==b)return this.empty().append((this[0]&&this[0].ownerDocument||c).createTextNode(a));return f.text(this)},wrapAll:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapAll(a.call(this,b))});if(this[0]){var b=f(a,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstChild&&a.firstChild.nodeType===1)a=a.firstChild;return a}).append(this)}return this},wrapInner:function(a){if(f.isFunction(a))return this.each(function(b){f(this).wrapInner(a.call(this,b))});return this.each(function(){var b=f(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){f(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){f.nodeName(this,"body")||f(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.appendChild(a)})},prepend:function(){return this.domManip(arguments,!0,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this)});if(arguments.length){var a=f(arguments[0]);a.push.apply(a,this.toArray());return this.pushStack(a,"before",arguments)}},after:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,!1,function(a){this.parentNode.insertBefore(a,this.nextSibling)});if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,f(arguments[0]).toArray());return a}},remove:function(a,b){for(var c=0,d;(d=this[c])!=null;c++)if(!a||f.filter(a,[d]).length)!b&&d.nodeType===1&&(f.cleanData(d.getElementsByTagName("*")),f.cleanData([d])),d.parentNode&&d.parentNode.removeChild(d);return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++){b.nodeType===1&&f.cleanData(b.getElementsByTagName("*"));while(b.firstChild)b.removeChild(b.firstChild)}return this},clone:function(a,b){a=a==null?!1:a,b=b==null?a:b;return this.map(function(){return f.clone(this,a,b)})},html:function(a){if(a===b)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(X,""):null;if(typeof a=="string"&&!bb.test(a)&&(f.support.leadingWhitespace||!Y.test(a))&&!bf[($.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Z,"<$1></$2>");try{for(var c=0,d=this.length;c<d;c++)this[c].nodeType===1&&(f.cleanData(this[c].getElementsByTagName("*")),this[c].innerHTML=a)}catch(e){this.empty().append(a)}}else f.isFunction(a)?this.each(function(b){var c=f(this);c.html(a.call(this,b,c.html()))}):this.empty().append(a);return this},replaceWith:function(a){if(this[0]&&this[0].parentNode){if(f.isFunction(a))return this.each(function(b){var c=f(this),d=c.html();c.replaceWith(a.call(this,b,d))});typeof a!="string"&&(a=f(a).detach());return this.each(function(){var b=this.nextSibling,c=this.parentNode;f(this).remove(),b?f(b).before(a):f(c).append(a)})}return this.length?this.pushStack(f(f.isFunction(a)?a():a),"replaceWith",a):this},detach:function(a){return this.remove(a,!0)},domManip:function(a,c,d){var e,g,h,i,j=a[0],k=[];if(!f.support.checkClone&&arguments.length===3&&typeof j=="string"&&bc.test(j))return this.each(function(){f(this).domManip(a,c,d,!0)});if(f.isFunction(j))return this.each(function(e){var g=f(this);a[0]=j.call(this,e,c?g.html():b),g.domManip(a,c,d)});if(this[0]){i=j&&j.parentNode,f.support.parentNode&&i&&i.nodeType===11&&i.childNodes.length===this.length?e={fragment:i}:e=f.buildFragment(a,this,k),h=e.fragment,h.childNodes.length===1?g=h=h.firstChild:g=h.firstChild;if(g){c=c&&f.nodeName(g,"tr");for(var l=0,m=this.length,n=m-1;l<m;l++)d.call(c?bg(this[l],g):this[l],e.cacheable||m>1&&l<n?f.clone(h,!0,!0):h)}k.length&&f.each(k,bm)}return this}}),f.buildFragment=function(a,b,d){var e,g,h,i;b&&b[0]&&(i=b[0].ownerDocument||b[0]),i.createDocumentFragment||(i=c),a.length===1&&typeof a[0]=="string"&&a[0].length<512&&i===c&&a[0].charAt(0)==="<"&&!bb.test(a[0])&&(f.support.checkClone||!bc.test(a[0]))&&(g=!0,h=f.fragments[a[0]],h&&h!==1&&(e=h)),e||(e=i.createDocumentFragment(),f.clean(a,i,e,d)),g&&(f.fragments[a[0]]=h?e:1);return{fragment:e,cacheable:g}},f.fragments={},f.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){f.fn[a]=function(c){var d=[],e=f(c),g=this.length===1&&this[0].parentNode;if(g&&g.nodeType===11&&g.childNodes.length===1&&e.length===1){e[b](this[0]);return this}for(var h=0,i=e.length;h<i;h++){var j=(h>0?this.clone(!0):this).get();f(e[h])[b](j),d=d.concat(j
-)}return this.pushStack(d,a,e.selector)}}),f.extend({clone:function(a,b,c){var d=a.cloneNode(!0),e,g,h;if((!f.support.noCloneEvent||!f.support.noCloneChecked)&&(a.nodeType===1||a.nodeType===11)&&!f.isXMLDoc(a)){bi(a,d),e=bj(a),g=bj(d);for(h=0;e[h];++h)bi(e[h],g[h])}if(b){bh(a,d);if(c){e=bj(a),g=bj(d);for(h=0;e[h];++h)bh(e[h],g[h])}}e=g=null;return d},clean:function(a,b,d,e){var g;b=b||c,typeof b.createElement=="undefined"&&(b=b.ownerDocument||b[0]&&b[0].ownerDocument||c);var h=[],i;for(var j=0,k;(k=a[j])!=null;j++){typeof k=="number"&&(k+="");if(!k)continue;if(typeof k=="string")if(!ba.test(k))k=b.createTextNode(k);else{k=k.replace(Z,"<$1></$2>");var l=($.exec(k)||["",""])[1].toLowerCase(),m=bf[l]||bf._default,n=m[0],o=b.createElement("div");o.innerHTML=m[1]+k+m[2];while(n--)o=o.lastChild;if(!f.support.tbody){var p=_.test(k),q=l==="table"&&!p?o.firstChild&&o.firstChild.childNodes:m[1]==="<table>"&&!p?o.childNodes:[];for(i=q.length-1;i>=0;--i)f.nodeName(q[i],"tbody")&&!q[i].childNodes.length&&q[i].parentNode.removeChild(q[i])}!f.support.leadingWhitespace&&Y.test(k)&&o.insertBefore(b.createTextNode(Y.exec(k)[0]),o.firstChild),k=o.childNodes}var r;if(!f.support.appendChecked)if(k[0]&&typeof (r=k.length)=="number")for(i=0;i<r;i++)bl(k[i]);else bl(k);k.nodeType?h.push(k):h=f.merge(h,k)}if(d){g=function(a){return!a.type||bd.test(a.type)};for(j=0;h[j];j++)if(e&&f.nodeName(h[j],"script")&&(!h[j].type||h[j].type.toLowerCase()==="text/javascript"))e.push(h[j].parentNode?h[j].parentNode.removeChild(h[j]):h[j]);else{if(h[j].nodeType===1){var s=f.grep(h[j].getElementsByTagName("script"),g);h.splice.apply(h,[j+1,0].concat(s))}d.appendChild(h[j])}}return h},cleanData:function(a){var b,c,d=f.cache,e=f.expando,g=f.event.special,h=f.support.deleteExpando;for(var i=0,j;(j=a[i])!=null;i++){if(j.nodeName&&f.noData[j.nodeName.toLowerCase()])continue;c=j[f.expando];if(c){b=d[c]&&d[c][e];if(b&&b.events){for(var k in b.events)g[k]?f.event.remove(j,k):f.removeEvent(j,k,b.handle);b.handle&&(b.handle.elem=null)}h?delete j[f.expando]:j.removeAttribute&&j.removeAttribute(f.expando),delete d[c]}}}});var bn=/alpha\([^)]*\)/i,bo=/opacity=([^)]*)/,bp=/([A-Z]|^ms)/g,bq=/^-?\d+(?:px)?$/i,br=/^-?\d/,bs=/^[+\-]=/,bt=/[^+\-\.\de]+/g,bu={position:"absolute",visibility:"hidden",display:"block"},bv=["Left","Right"],bw=["Top","Bottom"],bx,by,bz;f.fn.css=function(a,c){if(arguments.length===2&&c===b)return this;return f.access(this,a,c,!0,function(a,c,d){return d!==b?f.style(a,c,d):f.css(a,c)})},f.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=bx(a,"opacity","opacity");return c===""?"1":c}return a.style.opacity}}},cssNumber:{fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":f.support.cssFloat?"cssFloat":"styleFloat"},style:function(a,c,d,e){if(!!a&&a.nodeType!==3&&a.nodeType!==8&&!!a.style){var g,h,i=f.camelCase(c),j=a.style,k=f.cssHooks[i];c=f.cssProps[i]||i;if(d===b){if(k&&"get"in k&&(g=k.get(a,!1,e))!==b)return g;return j[c]}h=typeof d;if(h==="number"&&isNaN(d)||d==null)return;h==="string"&&bs.test(d)&&(d=+d.replace(bt,"")+parseFloat(f.css(a,c)),h="number"),h==="number"&&!f.cssNumber[i]&&(d+="px");if(!k||!("set"in k)||(d=k.set(a,d))!==b)try{j[c]=d}catch(l){}}},css:function(a,c,d){var e,g;c=f.camelCase(c),g=f.cssHooks[c],c=f.cssProps[c]||c,c==="cssFloat"&&(c="float");if(g&&"get"in g&&(e=g.get(a,!0,d))!==b)return e;if(bx)return bx(a,c)},swap:function(a,b,c){var d={};for(var e in b)d[e]=a.style[e],a.style[e]=b[e];c.call(a);for(e in b)a.style[e]=d[e]}}),f.curCSS=f.css,f.each(["height","width"],function(a,b){f.cssHooks[b]={get:function(a,c,d){var e;if(c){if(a.offsetWidth!==0)return bA(a,b,d);f.swap(a,bu,function(){e=bA(a,b,d)});return e}},set:function(a,b){if(!bq.test(b))return b;b=parseFloat(b);if(b>=0)return b+"px"}}}),f.support.opacity||(f.cssHooks.opacity={get:function(a,b){return bo.test((b&&a.currentStyle?a.currentStyle.filter:a.style.filter)||"")?parseFloat(RegExp.$1)/100+"":b?"1":""},set:function(a,b){var c=a.style,d=a.currentStyle;c.zoom=1;var e=f.isNaN(b)?"":"alpha(opacity="+b*100+")",g=d&&d.filter||c.filter||"";c.filter=bn.test(g)?g.replace(bn,e):g+" "+e}}),f(function(){f.support.reliableMarginRight||(f.cssHooks.marginRight={get:function(a,b){var c;f.swap(a,{display:"inline-block"},function(){b?c=bx(a,"margin-right","marginRight"):c=a.style.marginRight});return c}})}),c.defaultView&&c.defaultView.getComputedStyle&&(by=function(a,c){var d,e,g;c=c.replace(bp,"-$1").toLowerCase();if(!(e=a.ownerDocument.defaultView))return b;if(g=e.getComputedStyle(a,null))d=g.getPropertyValue(c),d===""&&!f.contains(a.ownerDocument.documentElement,a)&&(d=f.style(a,c));return d}),c.documentElement.currentStyle&&(bz=function(a,b){var c,d=a.currentStyle&&a.currentStyle[b],e=a.runtimeStyle&&a.runtimeStyle[b],f=a.style;!bq.test(d)&&br.test(d)&&(c=f.left,e&&(a.runtimeStyle.left=a.currentStyle.left),f.left=b==="fontSize"?"1em":d||0,d=f.pixelLeft+"px",f.left=c,e&&(a.runtimeStyle.left=e));return d===""?"auto":d}),bx=by||bz,f.expr&&f.expr.filters&&(f.expr.filters.hidden=function(a){var b=a.offsetWidth,c=a.offsetHeight;return b===0&&c===0||!f.support.reliableHiddenOffsets&&(a.style.display||f.css(a,"display"))==="none"},f.expr.filters.visible=function(a){return!f.expr.filters.hidden(a)});var bB=/%20/g,bC=/\[\]$/,bD=/\r?\n/g,bE=/#.*$/,bF=/^(.*?):[ \t]*([^\r\n]*)\r?$/mg,bG=/^(?:color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i,bH=/^(?:about|app|app\-storage|.+\-extension|file|widget):$/,bI=/^(?:GET|HEAD)$/,bJ=/^\/\//,bK=/\?/,bL=/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,bM=/^(?:select|textarea)/i,bN=/\s+/,bO=/([?&])_=[^&]*/,bP=/^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/,bQ=f.fn.load,bR={},bS={},bT,bU;try{bT=e.href}catch(bV){bT=c.createElement("a"),bT.href="",bT=bT.href}bU=bP.exec(bT.toLowerCase())||[],f.fn.extend({load:function(a,c,d){if(typeof a!="string"&&bQ)return bQ.apply(this,arguments);if(!this.length)return this;var e=a.indexOf(" ");if(e>=0){var g=a.slice(e,a.length);a=a.slice(0,e)}var h="GET";c&&(f.isFunction(c)?(d=c,c=b):typeof c=="object"&&(c=f.param(c,f.ajaxSettings.traditional),h="POST"));var i=this;f.ajax({url:a,type:h,dataType:"html",data:c,complete:function(a,b,c){c=a.responseText,a.isResolved()&&(a.done(function(a){c=a}),i.html(g?f("<div>").append(c.replace(bL,"")).find(g):c)),d&&i.each(d,[c,b,a])}});return this},serialize:function(){return f.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?f.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||bM.test(this.nodeName)||bG.test(this.type))}).map(function(a,b){var c=f(this).val();return c==null?null:f.isArray(c)?f.map(c,function(a,c){return{name:b.name,value:a.replace(bD,"\r\n")}}):{name:b.name,value:c.replace(bD,"\r\n")}}).get()}}),f.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "),function(a,b){f.fn[b]=function(a){return this.bind(b,a)}}),f.each(["get","post"],function(a,c){f[c]=function(a,d,e,g){f.isFunction(d)&&(g=g||e,e=d,d=b);return f.ajax({type:c,url:a,data:d,success:e,dataType:g})}}),f.extend({getScript:function(a,c){return f.get(a,b,c,"script")},getJSON:function(a,b,c){return f.get(a,b,c,"json")},ajaxSetup:function(a,b){b?f.extend(!0,a,f.ajaxSettings,b):(b=a,a=f.extend(!0,f.ajaxSettings,b));for(var c in{context:1,url:1})c in b?a[c]=b[c]:c in f.ajaxSettings&&(a[c]=f.ajaxSettings[c]);return a},ajaxSettings:{url:bT,isLocal:bH.test(bU[1]),global:!0,type:"GET",contentType:"application/x-www-form-urlencoded",processData:!0,async:!0,accepts:{xml:"application/xml, text/xml",html:"text/html",text:"text/plain",json:"application/json, text/javascript","*":"*/*"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":a.String,"text html":!0,"text json":f.parseJSON,"text xml":f.parseXML}},ajaxPrefilter:bW(bR),ajaxTransport:bW(bS),ajax:function(a,c){function w(a,c,l,m){if(s!==2){s=2,q&&clearTimeout(q),p=b,n=m||"",v.readyState=a?4:0;var o,r,u,w=l?bZ(d,v,l):b,x,y;if(a>=200&&a<300||a===304){if(d.ifModified){if(x=v.getResponseHeader("Last-Modified"))f.lastModified[k]=x;if(y=v.getResponseHeader("Etag"))f.etag[k]=y}if(a===304)c="notmodified",o=!0;else try{r=b$(d,w),c="success",o=!0}catch(z){c="parsererror",u=z}}else{u=c;if(!c||a)c="error",a<0&&(a=0)}v.status=a,v.statusText=c,o?h.resolveWith(e,[r,c,v]):h.rejectWith(e,[v,c,u]),v.statusCode(j),j=b,t&&g.trigger("ajax"+(o?"Success":"Error"),[v,d,o?r:u]),i.resolveWith(e,[v,c]),t&&(g.trigger("ajaxComplete",[v,d]),--f.active||f.event.trigger("ajaxStop"))}}typeof a=="object"&&(c=a,a=b),c=c||{};var d=f.ajaxSetup({},c),e=d.context||d,g=e!==d&&(e.nodeType||e instanceof f)?f(e):f.event,h=f.Deferred(),i=f._Deferred(),j=d.statusCode||{},k,l={},m={},n,o,p,q,r,s=0,t,u,v={readyState:0,setRequestHeader:function(a,b){if(!s){var c=a.toLowerCase();a=m[c]=m[c]||a,l[a]=b}return this},getAllResponseHeaders:function(){return s===2?n:null},getResponseHeader:function(a){var c;if(s===2){if(!o){o={};while(c=bF.exec(n))o[c[1].toLowerCase()]=c[2]}c=o[a.toLowerCase()]}return c===b?null:c},overrideMimeType:function(a){s||(d.mimeType=a);return this},abort:function(a){a=a||"abort",p&&p.abort(a),w(0,a);return this}};h.promise(v),v.success=v.done,v.error=v.fail,v.complete=i.done,v.statusCode=function(a){if(a){var b;if(s<2)for(b in a)j[b]=[j[b],a[b]];else b=a[v.status],v.then(b,b)}return this},d.url=((a||d.url)+"").replace(bE,"").replace(bJ,bU[1]+"//"),d.dataTypes=f.trim(d.dataType||"*").toLowerCase().split(bN),d.crossDomain==null&&(r=bP.exec(d.url.toLowerCase()),d.crossDomain=!(!r||r[1]==bU[1]&&r[2]==bU[2]&&(r[3]||(r[1]==="http:"?80:443))==(bU[3]||(bU[1]==="http:"?80:443)))),d.data&&d.processData&&typeof d.data!="string"&&(d.data=f.param(d.data,d.traditional)),bX(bR,d,c,v);if(s===2)return!1;t=d.global,d.type=d.type.toUpperCase(),d.hasContent=!bI.test(d.type),t&&f.active++===0&&f.event.trigger("ajaxStart");if(!d.hasContent){d.data&&(d.url+=(bK.test(d.url)?"&":"?")+d.data),k=d.url;if(d.cache===!1){var x=f.now(),y=d.url.replace(bO,"$1_="+x);d.url=y+(y===d.url?(bK.test(d.url)?"&":"?")+"_="+x:"")}}(d.data&&d.hasContent&&d.contentType!==!1||c.contentType)&&v.setRequestHeader("Content-Type",d.contentType),d.ifModified&&(k=k||d.url,f.lastModified[k]&&v.setRequestHeader("If-Modified-Since",f.lastModified[k]),f.etag[k]&&v.setRequestHeader("If-None-Match",f.etag[k])),v.setRequestHeader("Accept",d.dataTypes[0]&&d.accepts[d.dataTypes[0]]?d.accepts[d.dataTypes[0]]+(d.dataTypes[0]!=="*"?", */*; q=0.01":""):d.accepts["*"]);for(u in d.headers)v.setRequestHeader(u,d.headers[u]);if(d.beforeSend&&(d.beforeSend.call(e,v,d)===!1||s===2)){v.abort();return!1}for(u in{success:1,error:1,complete:1})v[u](d[u]);p=bX(bS,d,c,v);if(!p)w(-1,"No Transport");else{v.readyState=1,t&&g.trigger("ajaxSend",[v,d]),d.async&&d.timeout>0&&(q=setTimeout(function(){v.abort("timeout")},d.timeout));try{s=1,p.send(l,w)}catch(z){status<2?w(-1,z):f.error(z)}}return v},param:function(a,c){var d=[],e=function(a,b){b=f.isFunction(b)?b():b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};c===b&&(c=f.ajaxSettings.traditional);if(f.isArray(a)||a.jquery&&!f.isPlainObject(a))f.each(a,function(){e(this.name,this.value)});else for(var g in a)bY(g,a[g],c,e);return d.join("&").replace(bB,"+")}}),f.extend({active:0,lastModified:{},etag:{}});var b_=f.now(),ca=/(\=)\?(&|$)|\?\?/i;f.ajaxSetup({jsonp:"callback",jsonpCallback:function(){return f.expando+"_"+b_++}}),f.ajaxPrefilter("json jsonp",function(b,c,d){var e=b.contentType==="application/x-www-form-urlencoded"&&typeof b.data=="string";if(b.dataTypes[0]==="jsonp"||b.jsonp!==!1&&(ca.test(b.url)||e&&ca.test(b.data))){var g,h=b.jsonpCallback=f.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,i=a[h],j=b.url,k=b.data,l="$1"+h+"$2";b.jsonp!==!1&&(j=j.replace(ca,l),b.url===j&&(e&&(k=k.replace(ca,l)),b.data===k&&(j+=(/\?/.test(j)?"&":"?")+b.jsonp+"="+h))),b.url=j,b.data=k,a[h]=function(a){g=[a]},d.always(function(){a[h]=i,g&&f.isFunction(i)&&a[h](g[0])}),b.converters["script json"]=function(){g||f.error(h+" was not called");return g[0]},b.dataTypes[0]="json";return"script"}}),f.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/javascript|ecmascript/},converters:{"text script":function(a){f.globalEval(a);return a}}}),f.ajaxPrefilter("script",function(a){a.cache===b&&(a.cache=!1),a.crossDomain&&(a.type="GET",a.global=!1)}),f.ajaxTransport("script",function(a){if(a.crossDomain){var d,e=c.head||c.getElementsByTagName("head")[0]||c.documentElement;return{send:function(f,g){d=c.createElement("script"),d.async="async",a.scriptCharset&&(d.charset=a.scriptCharset),d.src=a.url,d.onload=d.onreadystatechange=function(a,c){if(c||!d.readyState||/loaded|complete/.test(d.readyState))d.onload=d.onreadystatechange=null,e&&d.parentNode&&e.removeChild(d),d=b,c||g(200,"success")},e.insertBefore(d,e.firstChild)},abort:function(){d&&d.onload(0,1)}}}});var cb=a.ActiveXObject?function(){for(var a in cd)cd[a](0,1)}:!1,cc=0,cd;f.ajaxSettings.xhr=a.ActiveXObject?function(){return!this.isLocal&&ce()||cf()}:ce,function(a){f.extend(f.support,{ajax:!!a,cors:!!a&&"withCredentials"in a})}(f.ajaxSettings.xhr()),f.support.ajax&&f.ajaxTransport(function(c){if(!c.crossDomain||f.support.cors){var d;return{send:function(e,g){var h=c.xhr(),i,j;c.username?h.open(c.type,c.url,c.async,c.username,c.password):h.open(c.type,c.url,c.async);if(c.xhrFields)for(j in c.xhrFields)h[j]=c.xhrFields[j];c.mimeType&&h.overrideMimeType&&h.overrideMimeType(c.mimeType),!c.crossDomain&&!e["X-Requested-With"]&&(e["X-Requested-With"]="XMLHttpRequest");try{for(j in e)h.setRequestHeader(j,e[j])}catch(k){}h.send(c.hasContent&&c.data||null),d=function(a,e){var j,k,l,m,n;try{if(d&&(e||h.readyState===4)){d=b,i&&(h.onreadystatechange=f.noop,cb&&delete cd[i]);if(e)h.readyState!==4&&h.abort();else{j=h.status,l=h.getAllResponseHeaders(),m={},n=h.responseXML,n&&n.documentElement&&(m.xml=n),m.text=h.responseText;try{k=h.statusText}catch(o){k=""}!j&&c.isLocal&&!c.crossDomain?j=m.text?200:404:j===1223&&(j=204)}}}catch(p){e||g(-1,p)}m&&g(j,k,m,l)},!c.async||h.readyState===4?d():(i=++cc,cb&&(cd||(cd={},f(a).unload(cb)),cd[i]=d),h.onreadystatechange=d)},abort:function(){d&&d(0,1)}}}});var cg={},ch,ci,cj=/^(?:toggle|show|hide)$/,ck=/^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i,cl,cm=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]],cn,co=a.webkitRequestAnimationFrame||a.mozRequestAnimationFrame||a.oRequestAnimationFrame;f.fn.extend({show:function(a,b,c){var d,e;if(a||a===0)return this.animate(cr("show",3),a,b,c);for(var g=0,h=this.length;g<h;g++)d=this[g],d.style&&(e=d.style.display,!f._data(d,"olddisplay")&&e==="none"&&(e=d.style.display=""),e===""&&f.css(d,"display")==="none"&&f._data(d,"olddisplay",cs(d.nodeName)));for(g=0;g<h;g++){d=this[g];if(d.style){e=d.style.display;if(e===""||e==="none")d.style.display=f._data(d,"olddisplay")||""}}return this},hide:function(a,b,c){if(a||a===0)return this.animate(cr("hide",3),a,b,c);for(var d=0,e=this.length;d<e;d++)if(this[d].style){var g=f.css(this[d],"display");g!=="none"&&!f._data(this[d],"olddisplay")&&f._data(this[d],"olddisplay",g)}for(d=0;d<e;d++)this[d].style&&(this[d].style.display="none");return this},_toggle:f.fn.toggle,toggle:function(a,b,c){var d=typeof a=="boolean";f.isFunction(a)&&f.isFunction(b)?this._toggle.apply(this,arguments):a==null||d?this.each(function(){var b=d?a:f(this).is(":hidden");f(this)[b?"show":"hide"]()}):this.animate(cr("toggle",3),a,b,c);return this},fadeTo:function(a,b,c,d){return this.filter(":hidden").css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=f.speed(b,c,d);if(f.isEmptyObject(a))return this.each(e.complete,[!1]);a=f.extend({},a);return this[e.queue===!1?"each":"queue"](function(){e.queue===!1&&f._mark(this);var b=f.extend({},e),c=this.nodeType===1,d=c&&f(this).is(":hidden"),g,h,i,j,k,l,m,n,o;b.animatedProperties={};for(i in a){g=f.camelCase(i),i!==g&&(a[g]=a[i],delete a[i]),h=a[g],f.isArray(h)?(b.animatedProperties[g]=h[1],h=a[g]=h[0]):b.animatedProperties[g]=b.specialEasing&&b.specialEasing[g]||b.easing||"swing";if(h==="hide"&&d||h==="show"&&!d)return b.complete.call(this);c&&(g==="height"||g==="width")&&(b.overflow=[this.style.overflow,this.style.overflowX,this.style.overflowY],f.css(this,"display")==="inline"&&f.css(this,"float")==="none"&&(f.support.inlineBlockNeedsLayout?(j=cs(this.nodeName),j==="inline"?this.style.display="inline-block":(this.style.display="inline",this.style.zoom=1)):this.style.display="inline-block"))}b.overflow!=null&&(this.style.overflow="hidden");for(i in a)k=new f.fx(this,b,i),h=a[i],cj.test(h)?k[h==="toggle"?d?"show":"hide":h]():(l=ck.exec(h),m=k.cur(),l?(n=parseFloat(l[2]),o=l[3]||(f.cssNumber[i]?"":"px"),o!=="px"&&(f.style(this,i,(n||1)+o),m=(n||1)/k.cur()*m,f.style(this,i,m+o)),l[1]&&(n=(l[1]==="-="?-1:1)*n+m),k.custom(m,n,o)):k.custom(m,h,""));return!0})},stop:function(a,b){a&&this.queue([]),this.each(function(){var a=f.timers,c=a.length;b||f._unmark(!0,this);while(c--)a[c].elem===this&&(b&&a[c](!0),a.splice(c,1))}),b||this.dequeue();return this}}),f.each({slideDown:cr("show",1),slideUp:cr("hide",1),slideToggle:cr("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){f.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),f.extend({speed:function(a,b,c){var d=a&&typeof a=="object"?f.extend({},a):{complete:c||!c&&b||f.isFunction(a)&&a,duration:a,easing:c&&b||b&&!f.isFunction(b)&&b};d.duration=f.fx.off?0:typeof d.duration=="number"?d.duration:d.duration in f.fx.speeds?f.fx.speeds[d.duration]:f.fx.speeds._default,d.old=d.complete,d.complete=function(a){f.isFunction(d.old)&&d.old.call(this),d.queue!==!1?f.dequeue(this):a!==!1&&f._unmark(this)};return d},easing:{linear:function(a,b,c,d){return c+d*a},swing:function(a,b,c,d){return(-Math.cos(a*Math.PI)/2+.5)*d+c}},timers:[],fx:function(a,b,c){this.options=b,this.elem=a,this.prop=c,b.orig=b.orig||{}}}),f.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this),(f.fx.step[this.prop]||f.fx.step._default)(this)},cur:function(){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];var a,b=f.css(this.elem,this.prop);return isNaN(a=parseFloat(b))?!b||b==="auto"?0:b:a},custom:function(a,b,c){function h(a){return d.step(a)}var d=this,e=f.fx,g;this.startTime=cn||cp(),this.start=a,this.end=b,this.unit=c||this.unit||(f.cssNumber[this.prop]?"":"px"),this.now=this.start,this.pos=this.state=0,h.elem=this.elem,h()&&f.timers.push(h)&&!cl&&(co?(cl=!0,g=function(){cl&&(co(g),e.tick())},co(g)):cl=setInterval(e.tick,e.interval))},show:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.show=!0,this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur()),f(this.elem).show()},hide:function(){this.options.orig[this.prop]=f.style(this.elem,this.prop),this.options.hide=!0,this.custom(this.cur(),0)},step:function(a){var b=cn||cp(),c=!0,d=this.elem,e=this.options,g,h;if(a||b>=e.duration+this.startTime){this.now=this.end,this.pos=this.state=1,this.update(),e.animatedProperties[this.prop]=!0;for(g in e.animatedProperties)e.animatedProperties[g]!==!0&&(c=!1);if(c){e.overflow!=null&&!f.support.shrinkWrapBlocks&&f.each(["","X","Y"],function(a,b){d.style["overflow"+b]=e.overflow[a]}),e.hide&&f(d).hide();if(e.hide||e.show)for(var i in e.animatedProperties)f.style(d,i,e.orig[i]);e.complete.call(d)}return!1}e.duration==Infinity?this.now=b:(h=b-this.startTime,this.state=h/e.duration,this.pos=f.easing[e.animatedProperties[this.prop]](this.state,h,0,1,e.duration),this.now=this.start+(this.end-this.start)*this.pos),this.update();return!0}},f.extend(f.fx,{tick:function(){for(var a=f.timers,b=0;b<a.length;++b)a[b]()||a.splice(b--,1);a.length||f.fx.stop()},interval:13,stop:function(){clearInterval(cl),cl=null},speeds:{slow:600,fast:200,_default:400},step:{opacity:function(a){f.style(a.elem,"opacity",a.now)},_default:function(a){a.elem.style&&a.elem.style[a.prop]!=null?a.elem.style[a.prop]=(a.prop==="width"||a.prop==="height"?Math.max(0,a.now):a.now)+a.unit:a.elem[a.prop]=a.now}}}),f.expr&&f.expr.filters&&(f.expr.filters.animated=function(a){return f.grep(f.timers,function(b){return a===b.elem}).length});var ct=/^t(?:able|d|h)$/i,cu=/^(?:body|html)$/i;"getBoundingClientRect"in c.documentElement?f.fn.offset=function(a){var b=this[0],c;if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);try{c=b.getBoundingClientRect()}catch(d){}var e=b.ownerDocument,g=e.documentElement;if(!c||!f.contains(g,b))return c?{top:c.top,left:c.left}:{top:0,left:0};var h=e.body,i=cv(e),j=g.clientTop||h.clientTop||0,k=g.clientLeft||h.clientLeft||0,l=i.pageYOffset||f.support.boxModel&&g.scrollTop||h.scrollTop,m=i.pageXOffset||f.support.boxModel&&g.scrollLeft||h.scrollLeft,n=c.top+l-j,o=c.left+m-k;return{top:n,left:o}}:f.fn.offset=function(a){var b=this[0];if(a)return this.each(function(b){f.offset.setOffset(this,a,b)});if(!b||!b.ownerDocument)return null;if(b===b.ownerDocument.body)return f.offset.bodyOffset(b);f.offset.initialize();var c,d=b.offsetParent,e=b,g=b.ownerDocument,h=g.documentElement,i=g.body,j=g.defaultView,k=j?j.getComputedStyle(b,null):b.currentStyle,l=b.offsetTop,m=b.offsetLeft;while((b=b.parentNode)&&b!==i&&b!==h){if(f.offset.supportsFixedPosition&&k.position==="fixed")break;c=j?j.getComputedStyle(b,null):b.currentStyle,l-=b.scrollTop,m-=b.scrollLeft,b===d&&(l+=b.offsetTop,m+=b.offsetLeft,f.offset.doesNotAddBorder&&(!f.offset.doesAddBorderForTableAndCells||!ct.test(b.nodeName))&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),e=d,d=b.offsetParent),f.offset.subtractsBorderForOverflowNotVisible&&c.overflow!=="visible"&&(l+=parseFloat(c.borderTopWidth)||0,m+=parseFloat(c.borderLeftWidth)||0),k=c}if(k.position==="relative"||k.position==="static")l+=i.offsetTop,m+=i.offsetLeft;f.offset.supportsFixedPosition&&k.position==="fixed"&&(l+=Math.max(h.scrollTop,i.scrollTop),m+=Math.max(h.scrollLeft,i.scrollLeft));return{top:l,left:m}},f.offset={initialize:function(){var a=c.body,b=c.createElement("div"),d,e,g,h,i=parseFloat(f.css(a,"marginTop"))||0,j="<div style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;'><div></div></div><table style='position:absolute;top:0;left:0;margin:0;border:5px solid #000;padding:0;width:1px;height:1px;' cellpadding='0' cellspacing='0'><tr><td></td></tr></table>";f.extend(b.style,{position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"}),b.innerHTML=j,a.insertBefore(b,a.firstChild),d=b.firstChild,e=d.firstChild,h=d.nextSibling.firstChild.firstChild,this.doesNotAddBorder=e.offsetTop!==5,this.doesAddBorderForTableAndCells=h.offsetTop===5,e.style.position="fixed",e.style.top="20px",this.supportsFixedPosition=e.offsetTop===20||e.offsetTop===15,e.style.position=e.style.top="",d.style.overflow="hidden",d.style.position="relative",this.subtractsBorderForOverflowNotVisible=e.offsetTop===-5,this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==i,a.removeChild(b),f.offset.initialize=f.noop},bodyOffset:function(a){var b=a.offsetTop,c=a.offsetLeft;f.offset.initialize(),f.offset.doesNotIncludeMarginInBodyOffset&&(b+=parseFloat(f.css(a,"marginTop"))||0,c+=parseFloat(f.css(a,"marginLeft"))||0);return{top:b,left:c}},setOffset:function(a,b,c){var d=f.css(a,"position");d==="static"&&(a.style.position="relative");var e=f(a),g=e.offset(),h=f.css(a,"top"),i=f.css(a,"left"),j=(d==="absolute"||d==="fixed")&&f.inArray("auto",[h,i])>-1,k={},l={},m,n;j?(l=e.position(),m=l.top,n=l.left):(m=parseFloat(h)||0,n=parseFloat(i)||0),f.isFunction(b)&&(b=b.call(a,c,g)),b.top!=null&&(k.top=b.top-g.top+m),b.left!=null&&(k.left=b.left-g.left+n),"using"in b?b.using.call(a,k):e.css(k)}},f.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),c=this.offset(),d=cu.test(b[0].nodeName)?{top:0,left:0}:b.offset();c.top-=parseFloat(f.css(a,"marginTop"))||0,c.left-=parseFloat(f.css(a,"marginLeft"))||0,d.top+=parseFloat(f.css(b[0],"borderTopWidth"))||0,d.left+=parseFloat(f.css(b[0],"borderLeftWidth"))||0;return{top:c.top-d.top,left:c.left-d.left}},offsetParent:function(){return this.map(function(){var a=this.offsetParent||c.body;while(a&&!cu.test(a.nodeName)&&f.css(a,"position")==="static")a=a.offsetParent;return a})}}),f.each(["Left","Top"],function(a,c){var d="scroll"+c;f.fn[d]=function(c){var e,g;if(c===b){e=this[0];if(!e)return null;g=cv(e);return g?"pageXOffset"in g?g[a?"pageYOffset":"pageXOffset"]:f.support.boxModel&&g.document.documentElement[d]||g.document.body[d]:e[d]}return this.each(function(){g=cv(this),g?g.scrollTo(a?f(g).scrollLeft():c,a?c:f(g).scrollTop()):this[d]=c})}}),f.each(["Height","Width"],function(a,c){var d=c.toLowerCase();f.fn["inner"+c]=function(){var a=this[0];return a&&a.style?parseFloat(f.css(a,d,"padding")):null},f.fn["outer"+c]=function(a){var b=this[0];return b&&b.style?parseFloat(f.css(b,d,a?"margin":"border")):null},f.fn[d]=function(a){var e=this[0];if(!e)return a==null?null:this;if(f.isFunction(a))return this.each(function(b){var c=f(this);c[d](a.call(this,b,c[d]()))});if(f.isWindow(e)){var g=e.document.documentElement["client"+c];return e.document.compatMode==="CSS1Compat"&&g||e.document.body["client"+c]||g}if(e.nodeType===9)return Math.max(e.documentElement["client"+c],e.body["scroll"+c],e.documentElement["scroll"+c],e.body["offset"+c],e.documentElement["offset"+c]);if(a===b){var h=f.css(e,d),i=parseFloat(h);return f.isNaN(i)?h:i}return this.css(d,typeof a=="string"?a:a+"px")}}),a.jQuery=a.$=f})(window); \ No newline at end of file
diff --git a/app/assets/javascripts/vendor/jquery.condom.js b/app/assets/javascripts/vendor/jquery.condom.js
deleted file mode 100644
index 5d24a7e..0000000
--- a/app/assets/javascripts/vendor/jquery.condom.js
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * jQuery Condom (Use namespaces to protect your global integrity.)
- * Version 0.0.3
- *
- * Copyright (c) 2011 Mario "Kuroir" Ricalde (http://kuroir.com)
- * & Micha Niskin (micha@thinkminimo.com)
- * Licensed jointly under the GPL and MIT licenses,
- * choose which one suits your project best!
- */
-(function($) {
- var methods = {};
- $.ns = function(ns) {
- // Define namespace if it doesn't exist.
- methods[ns] = methods[ns] || {};
-
- // Get reference to a namespaced jQ object
- function nsfun(selector, context) {
- return $(selector, context).ns(ns);
- }
-
- // Allows you to add methods ala jQuery.fn (useful to namespace premade plugins)
- nsfun.fn = methods[ns];
-
- // Add a method.
- nsfun.add = function(fname, fn) {
- var new_funcs = typeof fname == "object" ? fname : {};
- // One method.
- if (new_funcs !== fname)
- new_funcs[fname] = fn;
- // Group of methods.
- $.each(new_funcs, function(fname, fn) {
- methods[ns][fname] = function() {
- fn.apply(this, arguments);
- return this;
- };
- });
- return this;
- };
-
- // Get methods.
- nsfun.methods = function() {
- return $.extend({}, methods[ns]);
- };
-
- return nsfun;
- };
- // The only function that touches $.fn
- $.fn.ns = function(ns) {
- if (methods[ns]) $.extend(this, methods[ns]);
- return this;
- };
-})(jQuery);
diff --git a/app/assets/javascripts/vendor/jquery.easy-slider-1.7.js b/app/assets/javascripts/vendor/jquery.easy-slider-1.7.js
deleted file mode 100644
index ff5518f..0000000
--- a/app/assets/javascripts/vendor/jquery.easy-slider-1.7.js
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
- * Easy Slider 1.7 - jQuery plugin
- * written by Alen Grakalic
- * http://cssglobe.com/post/4004/easy-slider-15-the-easiest-jquery-plugin-for-sliding
- *
- * Copyright (c) 2009 Alen Grakalic (http://cssglobe.com)
- * Dual licensed under the MIT (MIT-LICENSE.txt)
- * and GPL (GPL-LICENSE.txt) licenses.
- *
- * Built for jQuery library
- * http://jquery.com
- *
- */
-
-/*
- * markup example for $("#slider").easySlider();
- *
- * <div id="slider">
- * <ul>
- * <li><img src="images/01.jpg" alt="" /></li>
- * <li><img src="images/02.jpg" alt="" /></li>
- * <li><img src="images/03.jpg" alt="" /></li>
- * <li><img src="images/04.jpg" alt="" /></li>
- * <li><img src="images/05.jpg" alt="" /></li>
- * </ul>
- * </div>
- *
- */
-
-(function($) {
-
- $.fn.easySlider = function(options){
-
- // default configuration properties
- var defaults = {
- prevId: 'prevBtn',
- prevText: 'Previous',
- nextId: 'nextBtn',
- nextText: 'Next',
- controlsShow: true,
- controlsBefore: '',
- controlsAfter: '',
- controlsFade: true,
- firstId: 'firstBtn',
- firstText: 'First',
- firstShow: false,
- lastId: 'lastBtn',
- lastText: 'Last',
- lastShow: false,
- vertical: false,
- speed: 800,
- auto: false,
- pause: 2000,
- continuous: false,
- numeric: false,
- numericId: 'controls'
- };
-
- var options = $.extend(defaults, options);
-
- this.each(function() {
- var obj = $(this);
- var s = $("li", obj).length;
- var w = $("li", obj).width();
- var h = $("li", obj).height();
- var clickable = true;
- obj.width(w);
- obj.height(h);
- obj.css("overflow","hidden");
- var ts = s-1;
- var t = 0;
- $("ul", obj).css('width',s*w);
-
- if(options.continuous){
- $("ul", obj).prepend($("ul li:last-child", obj).clone().css("margin-left","-"+ w +"px"));
- $("ul", obj).append($("ul li:nth-child(2)", obj).clone());
- $("ul", obj).css('width',(s+1)*w);
- };
-
- if(!options.vertical) $("li", obj).css('float','left');
-
- if(options.controlsShow){
- var html = options.controlsBefore;
- if(options.numeric){
- html += '<ol id="'+ options.numericId +'"></ol>';
- } else {
- if(options.firstShow) html += '<span id="'+ options.firstId +'"><a href=\"javascript:void(0);\">'+ options.firstText +'</a></span>';
- html += ' <span id="'+ options.prevId +'"><a href=\"javascript:void(0);\">'+ options.prevText +'</a></span>';
- html += ' <span id="'+ options.nextId +'"><a href=\"javascript:void(0);\">'+ options.nextText +'</a></span>';
- if(options.lastShow) html += ' <span id="'+ options.lastId +'"><a href=\"javascript:void(0);\">'+ options.lastText +'</a></span>';
- };
-
- html += options.controlsAfter;
- $(obj).after(html);
- };
-
- if(options.numeric){
- for(var i=0;i<s;i++){
- $(document.createElement("li"))
- .attr('id',options.numericId + (i+1))
- .html('<a rel='+ i +' href=\"javascript:void(0);\">'+ (i+1) +'</a>')
- .appendTo($("#"+ options.numericId))
- .click(function(){
- animate($("a",$(this)).attr('rel'),true);
- });
- };
- } else {
- $("a","#"+options.nextId).click(function(){
- animate("next",true);
- });
- $("a","#"+options.prevId).click(function(){
- animate("prev",true);
- });
- $("a","#"+options.firstId).click(function(){
- animate("first",true);
- });
- $("a","#"+options.lastId).click(function(){
- animate("last",true);
- });
- };
-
- function setCurrent(i){
- i = parseInt(i)+1;
- $("li", "#" + options.numericId).removeClass("current");
- $("li#" + options.numericId + i).addClass("current");
- };
-
- function adjust(){
- if(t>ts) t=0;
- if(t<0) t=ts;
- if(!options.vertical) {
- $("ul",obj).css("margin-left",(t*w*-1));
- } else {
- $("ul",obj).css("margin-left",(t*h*-1));
- }
- clickable = true;
- if(options.numeric) setCurrent(t);
- };
-
- function animate(dir,clicked){
- if (clickable){
- clickable = false;
- var ot = t;
- switch(dir){
- case "next":
- t = (ot>=ts) ? (options.continuous ? t+1 : ts) : t+1;
- break;
- case "prev":
- t = (t<=0) ? (options.continuous ? t-1 : 0) : t-1;
- break;
- case "first":
- t = 0;
- break;
- case "last":
- t = ts;
- break;
- default:
- t = dir;
- break;
- };
- var diff = Math.abs(ot-t);
- var speed = diff*options.speed;
- if(!options.vertical) {
- p = (t*w*-1);
- $("ul",obj).animate(
- { marginLeft: p },
- { queue:false, duration:speed, complete:adjust }
- );
- } else {
- p = (t*h*-1);
- $("ul",obj).animate(
- { marginTop: p },
- { queue:false, duration:speed, complete:adjust }
- );
- };
-
- if(!options.continuous && options.controlsFade){
- if(t==ts){
- $("a","#"+options.nextId).hide();
- $("a","#"+options.lastId).hide();
- } else {
- $("a","#"+options.nextId).show();
- $("a","#"+options.lastId).show();
- };
- if(t==0){
- $("a","#"+options.prevId).hide();
- $("a","#"+options.firstId).hide();
- } else {
- $("a","#"+options.prevId).show();
- $("a","#"+options.firstId).show();
- };
- };
-
- if(clicked) clearTimeout(timeout);
- if(options.auto && dir=="next" && !clicked){;
- timeout = setTimeout(function(){
- animate("next",false);
- },diff*options.speed+options.pause);
- };
-
- };
-
- };
- // init
- var timeout;
- if(options.auto){;
- timeout = setTimeout(function(){
- animate("next",false);
- },options.pause);
- };
-
- if(options.numeric) setCurrent(0);
-
- if(!options.continuous && options.controlsFade){
- $("a","#"+options.prevId).hide();
- $("a","#"+options.firstId).hide();
- };
-
- });
-
- };
-
-})(jQuery);
-
-
diff --git a/app/assets/javascripts/vendor/jquery.survival-kit.coffee b/app/assets/javascripts/vendor/jquery.survival-kit.coffee
deleted file mode 100644
index 654e167..0000000
--- a/app/assets/javascripts/vendor/jquery.survival-kit.coffee
+++ /dev/null
@@ -1,36 +0,0 @@
-Array.prototype.empty = ->
- if this.length <= 0
- return true
- else
- return false
-
-$.ns('sk').add {
- # Search Box Helper
- searchBox: ->
- input = $('input.text', this)
- default_mes = input.val()
- input.focus(->
- if input.val() == default_mes
- input.val ''
- ).blur(->
- if input.val() == ''
- input.val default_mes
- )
-
- # Simple Form Style Helper.
- simpleForms: ->
- max = 0
- labels = $("div:not(.boolean) > label", this)
- hints = $("div:not(.boolean) > .hint", this)
- labels.each ->
- if $(this).width() > max
- max = $(this).width()
- $('> .hint.padded', this).css 'padding-left' : max
-
- # Get the horizontal-spacing (set on the css.)
- horizontal_spacing = parseInt(labels.first().css('margin-right'))
-
- hints.css 'padding-left' : (max + horizontal_spacing)
- $('.actions', this).css 'padding-left' : (max + horizontal_spacing)
- labels.width(max)
-}
diff --git a/app/assets/javascripts/vendor/jquery.tmpl.js b/app/assets/javascripts/vendor/jquery.tmpl.js
deleted file mode 100644
index a819d61..0000000
--- a/app/assets/javascripts/vendor/jquery.tmpl.js
+++ /dev/null
@@ -1,486 +0,0 @@
-/*
- * jQuery Templating Plugin
- * Copyright 2010, John Resig
- * Dual licensed under the MIT or GPL Version 2 licenses.
- */
-(function( jQuery, undefined ){
- var oldManip = jQuery.fn.domManip, tmplItmAtt = "_tmplitem", htmlExpr = /^[^<]*(<[\w\W]+>)[^>]*$|\{\{\! /,
- newTmplItems = {}, wrappedItems = {}, appendToTmplItems, topTmplItem = { key: 0, data: {} }, itemKey = 0, cloneIndex = 0, stack = [];
-
- function newTmplItem( options, parentItem, fn, data ) {
- // Returns a template item data structure for a new rendered instance of a template (a 'template item').
- // The content field is a hierarchical array of strings and nested items (to be
- // removed and replaced by nodes field of dom elements, once inserted in DOM).
- var newItem = {
- data: data || (parentItem ? parentItem.data : {}),
- _wrap: parentItem ? parentItem._wrap : null,
- tmpl: null,
- parent: parentItem || null,
- nodes: [],
- calls: tiCalls,
- nest: tiNest,
- wrap: tiWrap,
- html: tiHtml,
- update: tiUpdate
- };
- if ( options ) {
- jQuery.extend( newItem, options, { nodes: [], parent: parentItem } );
- }
- if ( fn ) {
- // Build the hierarchical content to be used during insertion into DOM
- newItem.tmpl = fn;
- newItem._ctnt = newItem._ctnt || newItem.tmpl( jQuery, newItem );
- newItem.key = ++itemKey;
- // Keep track of new template item, until it is stored as jQuery Data on DOM element
- (stack.length ? wrappedItems : newTmplItems)[itemKey] = newItem;
- }
- return newItem;
- }
-
- // Override appendTo etc., in order to provide support for targeting multiple elements. (This code would disappear if integrated in jquery core).
- jQuery.each({
- appendTo: "append",
- prependTo: "prepend",
- insertBefore: "before",
- insertAfter: "after",
- replaceAll: "replaceWith"
- }, function( name, original ) {
- jQuery.fn[ name ] = function( selector ) {
- var ret = [], insert = jQuery( selector ), elems, i, l, tmplItems,
- parent = this.length === 1 && this[0].parentNode;
-
- appendToTmplItems = newTmplItems || {};
- if ( parent && parent.nodeType === 11 && parent.childNodes.length === 1 && insert.length === 1 ) {
- insert[ original ]( this[0] );
- ret = this;
- } else {
- for ( i = 0, l = insert.length; i < l; i++ ) {
- cloneIndex = i;
- elems = (i > 0 ? this.clone(true) : this).get();
- jQuery.fn[ original ].apply( jQuery(insert[i]), elems );
- ret = ret.concat( elems );
- }
- cloneIndex = 0;
- ret = this.pushStack( ret, name, insert.selector );
- }
- tmplItems = appendToTmplItems;
- appendToTmplItems = null;
- jQuery.tmpl.complete( tmplItems );
- return ret;
- };
- });
-
- jQuery.fn.extend({
- // Use first wrapped element as template markup.
- // Return wrapped set of template items, obtained by rendering template against data.
- tmpl: function( data, options, parentItem ) {
- return jQuery.tmpl( this[0], data, options, parentItem );
- },
-
- // Find which rendered template item the first wrapped DOM element belongs to
- tmplItem: function() {
- return jQuery.tmplItem( this[0] );
- },
-
- // Consider the first wrapped element as a template declaration, and get the compiled template or store it as a named template.
- template: function( name ) {
- return jQuery.template( name, this[0] );
- },
-
- domManip: function( args, table, callback, options ) {
- // This appears to be a bug in the appendTo, etc. implementation
- // it should be doing .call() instead of .apply(). See #6227
- if ( args[0] && args[0].nodeType ) {
- var dmArgs = jQuery.makeArray( arguments ), argsLength = args.length, i = 0, tmplItem;
- while ( i < argsLength && !(tmplItem = jQuery.data( args[i++], "tmplItem" ))) {}
- if ( argsLength > 1 ) {
- dmArgs[0] = [jQuery.makeArray( args )];
- }
- if ( tmplItem && cloneIndex ) {
- dmArgs[2] = function( fragClone ) {
- // Handler called by oldManip when rendered template has been inserted into DOM.
- jQuery.tmpl.afterManip( this, fragClone, callback );
- };
- }
- oldManip.apply( this, dmArgs );
- } else {
- oldManip.apply( this, arguments );
- }
- cloneIndex = 0;
- if ( !appendToTmplItems ) {
- jQuery.tmpl.complete( newTmplItems );
- }
- return this;
- }
- });
-
- jQuery.extend({
- // Return wrapped set of template items, obtained by rendering template against data.
- tmpl: function( tmpl, data, options, parentItem ) {
- var ret, topLevel = !parentItem;
- if ( topLevel ) {
- // This is a top-level tmpl call (not from a nested template using {{tmpl}})
- parentItem = topTmplItem;
- tmpl = jQuery.template[tmpl] || jQuery.template( null, tmpl );
- wrappedItems = {}; // Any wrapped items will be rebuilt, since this is top level
- } else if ( !tmpl ) {
- // The template item is already associated with DOM - this is a refresh.
- // Re-evaluate rendered template for the parentItem
- tmpl = parentItem.tmpl;
- newTmplItems[parentItem.key] = parentItem;
- parentItem.nodes = [];
- if ( parentItem.wrapped ) {
- updateWrapped( parentItem, parentItem.wrapped );
- }
- // Rebuild, without creating a new template item
- return jQuery( build( parentItem, null, parentItem.tmpl( jQuery, parentItem ) ));
- }
- if ( !tmpl ) {
- return []; // Could throw...
- }
- if ( typeof data === "function" ) {
- data = data.call( parentItem || {} );
- }
- if ( options && options.wrapped ) {
- updateWrapped( options, options.wrapped );
- }
- ret = jQuery.isArray( data ) ?
- jQuery.map( data, function( dataItem ) {
- return dataItem ? newTmplItem( options, parentItem, tmpl, dataItem ) : null;
- }) :
- [ newTmplItem( options, parentItem, tmpl, data ) ];
- return topLevel ? jQuery( build( parentItem, null, ret ) ) : ret;
- },
-
- // Return rendered template item for an element.
- tmplItem: function( elem ) {
- var tmplItem;
- if ( elem instanceof jQuery ) {
- elem = elem[0];
- }
- while ( elem && elem.nodeType === 1 && !(tmplItem = jQuery.data( elem, "tmplItem" )) && (elem = elem.parentNode) ) {}
- return tmplItem || topTmplItem;
- },
-
- // Set:
- // Use $.template( name, tmpl ) to cache a named template,
- // where tmpl is a template string, a script element or a jQuery instance wrapping a script element, etc.
- // Use $( "selector" ).template( name ) to provide access by name to a script block template declaration.
-
- // Get:
- // Use $.template( name ) to access a cached template.
- // Also $( selectorToScriptBlock ).template(), or $.template( null, templateString )
- // will return the compiled template, without adding a name reference.
- // If templateString includes at least one HTML tag, $.template( templateString ) is equivalent
- // to $.template( null, templateString )
- template: function( name, tmpl ) {
- if (tmpl) {
- // Compile template and associate with name
- if ( typeof tmpl === "string" ) {
- // This is an HTML string being passed directly in.
- tmpl = buildTmplFn( tmpl )
- } else if ( tmpl instanceof jQuery ) {
- tmpl = tmpl[0] || {};
- }
- if ( tmpl.nodeType ) {
- // If this is a template block, use cached copy, or generate tmpl function and cache.
- tmpl = jQuery.data( tmpl, "tmpl" ) || jQuery.data( tmpl, "tmpl", buildTmplFn( tmpl.innerHTML ));
- }
- return typeof name === "string" ? (jQuery.template[name] = tmpl) : tmpl;
- }
- // Return named compiled template
- return name ? (typeof name !== "string" ? jQuery.template( null, name ):
- (jQuery.template[name] ||
- // If not in map, treat as a selector. (If integrated with core, use quickExpr.exec)
- jQuery.template( null, htmlExpr.test( name ) ? name : jQuery( name )))) : null;
- },
-
- encode: function( text ) {
- // Do HTML encoding replacing < > & and ' and " by corresponding entities.
- return ("" + text).split("<").join("&lt;").split(">").join("&gt;").split('"').join("&#34;").split("'").join("&#39;");
- }
- });
-
- jQuery.extend( jQuery.tmpl, {
- tag: {
- "tmpl": {
- _default: { $2: "null" },
- open: "if($notnull_1){_=_.concat($item.nest($1,$2));}"
- // tmpl target parameter can be of type function, so use $1, not $1a (so not auto detection of functions)
- // This means that {{tmpl foo}} treats foo as a template (which IS a function).
- // Explicit parens can be used if foo is a function that returns a template: {{tmpl foo()}}.
- },
- "wrap": {
- _default: { $2: "null" },
- open: "$item.calls(_,$1,$2);_=[];",
- close: "call=$item.calls();_=call._.concat($item.wrap(call,_));"
- },
- "each": {
- _default: { $2: "$index, $value" },
- open: "if($notnull_1){$.each($1a,function($2){with(this){",
- close: "}});}"
- },
- "if": {
- open: "if(($notnull_1) && $1a){",
- close: "}"
- },
- "else": {
- _default: { $1: "true" },
- open: "}else if(($notnull_1) && $1a){"
- },
- "html": {
- // Unecoded expression evaluation.
- open: "if($notnull_1){_.push($1a);}"
- },
- "=": {
- // Encoded expression evaluation. Abbreviated form is ${}.
- _default: { $1: "$data" },
- open: "if($notnull_1){_.push($.encode($1a));}"
- },
- "!": {
- // Comment tag. Skipped by parser
- open: ""
- }
- },
-
- // This stub can be overridden, e.g. in jquery.tmplPlus for providing rendered events
- complete: function( items ) {
- newTmplItems = {};
- },
-
- // Call this from code which overrides domManip, or equivalent
- // Manage cloning/storing template items etc.
- afterManip: function afterManip( elem, fragClone, callback ) {
- // Provides cloned fragment ready for fixup prior to and after insertion into DOM
- var content = fragClone.nodeType === 11 ?
- jQuery.makeArray(fragClone.childNodes) :
- fragClone.nodeType === 1 ? [fragClone] : [];
-
- // Return fragment to original caller (e.g. append) for DOM insertion
- callback.call( elem, fragClone );
-
- // Fragment has been inserted:- Add inserted nodes to tmplItem data structure. Replace inserted element annotations by jQuery.data.
- storeTmplItems( content );
- cloneIndex++;
- }
- });
-
- //========================== Private helper functions, used by code above ==========================
-
- function build( tmplItem, nested, content ) {
- // Convert hierarchical content into flat string array
- // and finally return array of fragments ready for DOM insertion
- var frag, ret = content ? jQuery.map( content, function( item ) {
- return (typeof item === "string") ?
- // Insert template item annotations, to be converted to jQuery.data( "tmplItem" ) when elems are inserted into DOM.
- (tmplItem.key ? item.replace( /(<\w+)(?=[\s>])(?![^>]*_tmplitem)([^>]*)/g, "$1 " + tmplItmAtt + "=\"" + tmplItem.key + "\" $2" ) : item) :
- // This is a child template item. Build nested template.
- build( item, tmplItem, item._ctnt );
- }) :
- // If content is not defined, insert tmplItem directly. Not a template item. May be a string, or a string array, e.g. from {{html $item.html()}}.
- tmplItem;
- if ( nested ) {
- return ret;
- }
-
- // top-level template
- ret = ret.join("");
-
- // Support templates which have initial or final text nodes, or consist only of text
- // Also support HTML entities within the HTML markup.
- ret.replace( /^\s*([^<\s][^<]*)?(<[\w\W]+>)([^>]*[^>\s])?\s*$/, function( all, before, middle, after) {
- frag = jQuery( middle ).get();
-
- storeTmplItems( frag );
- if ( before ) {
- frag = unencode( before ).concat(frag);
- }
- if ( after ) {
- frag = frag.concat(unencode( after ));
- }
- });
- return frag ? frag : unencode( ret );
- }
-
- function unencode( text ) {
- // Use createElement, since createTextNode will not render HTML entities correctly
- var el = document.createElement( "div" );
- el.innerHTML = text;
- return jQuery.makeArray(el.childNodes);
- }
-
- // Generate a reusable function that will serve to render a template against data
- function buildTmplFn( markup ) {
- return new Function("jQuery","$item",
- "var $=jQuery,call,_=[],$data=$item.data;" +
-
- // Introduce the data as local variables using with(){}
- "with($data){_.push('" +
-
- // Convert the template into pure JavaScript
- jQuery.trim(markup)
- .replace( /([\\'])/g, "\\$1" )
- .replace( /[\r\t\n]/g, " " )
- .replace( /\$\{([^\}]*)\}/g, "{{= $1}}" )
- .replace( /\{\{(\/?)(\w+|.)(?:\(((?:[^\}]|\}(?!\}))*?)?\))?(?:\s+(.*?)?)?(\(((?:[^\}]|\}(?!\}))*?)\))?\s*\}\}/g,
- function( all, slash, type, fnargs, target, parens, args ) {
- var tag = jQuery.tmpl.tag[ type ], def, expr, exprAutoFnDetect;
- if ( !tag ) {
- throw "Template command not found: " + type;
- }
- def = tag._default || [];
- if ( parens && !/\w$/.test(target)) {
- target += parens;
- parens = "";
- }
- if ( target ) {
- target = unescape( target );
- args = args ? ("," + unescape( args ) + ")") : (parens ? ")" : "");
- // Support for target being things like a.toLowerCase();
- // In that case don't call with template item as 'this' pointer. Just evaluate...
- expr = parens ? (target.indexOf(".") > -1 ? target + parens : ("(" + target + ").call($item" + args)) : target;
- exprAutoFnDetect = parens ? expr : "(typeof(" + target + ")==='function'?(" + target + ").call($item):(" + target + "))";
- } else {
- exprAutoFnDetect = expr = def.$1 || "null";
- }
- fnargs = unescape( fnargs );
- return "');" +
- tag[ slash ? "close" : "open" ]
- .split( "$notnull_1" ).join( target ? "typeof(" + target + ")!=='undefined' && (" + target + ")!=null" : "true" )
- .split( "$1a" ).join( exprAutoFnDetect )
- .split( "$1" ).join( expr )
- .split( "$2" ).join( fnargs ?
- fnargs.replace( /\s*([^\(]+)\s*(\((.*?)\))?/g, function( all, name, parens, params ) {
- params = params ? ("," + params + ")") : (parens ? ")" : "");
- return params ? ("(" + name + ").call($item" + params) : all;
- })
- : (def.$2||"")
- ) +
- "_.push('";
- }) +
- "');}return _;"
- );
- }
- function updateWrapped( options, wrapped ) {
- // Build the wrapped content.
- options._wrap = build( options, true,
- // Suport imperative scenario in which options.wrapped can be set to a selector or an HTML string.
- jQuery.isArray( wrapped ) ? wrapped : [htmlExpr.test( wrapped ) ? wrapped : jQuery( wrapped ).html()]
- ).join("");
- }
-
- function unescape( args ) {
- return args ? args.replace( /\\'/g, "'").replace(/\\\\/g, "\\" ) : null;
- }
- function outerHtml( elem ) {
- var div = document.createElement("div");
- div.appendChild( elem.cloneNode(true) );
- return div.innerHTML;
- }
-
- // Store template items in jQuery.data(), ensuring a unique tmplItem data data structure for each rendered template instance.
- function storeTmplItems( content ) {
- var keySuffix = "_" + cloneIndex, elem, elems, newClonedItems = {}, i, l, m;
- for ( i = 0, l = content.length; i < l; i++ ) {
- if ( (elem = content[i]).nodeType !== 1 ) {
- continue;
- }
- elems = elem.getElementsByTagName("*");
- for ( m = elems.length - 1; m >= 0; m-- ) {
- processItemKey( elems[m] );
- }
- processItemKey( elem );
- }
- function processItemKey( el ) {
- var pntKey, pntNode = el, pntItem, tmplItem, key;
- // Ensure that each rendered template inserted into the DOM has its own template item,
- if ( (key = el.getAttribute( tmplItmAtt ))) {
- while ( pntNode.parentNode && (pntNode = pntNode.parentNode).nodeType === 1 && !(pntKey = pntNode.getAttribute( tmplItmAtt ))) { }
- if ( pntKey !== key ) {
- // The next ancestor with a _tmplitem expando is on a different key than this one.
- // So this is a top-level element within this template item
- // Set pntNode to the key of the parentNode, or to 0 if pntNode.parentNode is null, or pntNode is a fragment.
- pntNode = pntNode.parentNode ? (pntNode.nodeType === 11 ? 0 : (pntNode.getAttribute( tmplItmAtt ) || 0)) : 0;
- if ( !(tmplItem = newTmplItems[key]) ) {
- // The item is for wrapped content, and was copied from the temporary parent wrappedItem.
- tmplItem = wrappedItems[key];
- tmplItem = newTmplItem( tmplItem, newTmplItems[pntNode]||wrappedItems[pntNode], null, true );
- tmplItem.key = ++itemKey;
- newTmplItems[itemKey] = tmplItem;
- }
- if ( cloneIndex ) {
- cloneTmplItem( key );
- }
- }
- el.removeAttribute( tmplItmAtt );
- } else if ( cloneIndex && (tmplItem = jQuery.data( el, "tmplItem" )) ) {
- // This was a rendered element, cloned during append or appendTo etc.
- // TmplItem stored in jQuery data has already been cloned in cloneCopyEvent. We must replace it with a fresh cloned tmplItem.
- cloneTmplItem( tmplItem.key );
- newTmplItems[tmplItem.key] = tmplItem;
- pntNode = jQuery.data( el.parentNode, "tmplItem" );
- pntNode = pntNode ? pntNode.key : 0;
- }
- if ( tmplItem ) {
- pntItem = tmplItem;
- // Find the template item of the parent element.
- // (Using !=, not !==, since pntItem.key is number, and pntNode may be a string)
- while ( pntItem && pntItem.key != pntNode ) {
- // Add this element as a top-level node for this rendered template item, as well as for any
- // ancestor items between this item and the item of its parent element
- pntItem.nodes.push( el );
- pntItem = pntItem.parent;
- }
- // Delete content built during rendering - reduce API surface area and memory use, and avoid exposing of stale data after rendering...
- delete tmplItem._ctnt;
- delete tmplItem._wrap;
- // Store template item as jQuery data on the element
- jQuery.data( el, "tmplItem", tmplItem );
- }
- function cloneTmplItem( key ) {
- key = key + keySuffix;
- tmplItem = newClonedItems[key] =
- (newClonedItems[key] || newTmplItem( tmplItem, newTmplItems[tmplItem.parent.key + keySuffix] || tmplItem.parent, null, true ));
- }
- }
- }
-
- //---- Helper functions for template item ----
-
- function tiCalls( content, tmpl, data, options ) {
- if ( !content ) {
- return stack.pop();
- }
- stack.push({ _: content, tmpl: tmpl, item:this, data: data, options: options });
- }
-
- function tiNest( tmpl, data, options ) {
- // nested template, using {{tmpl}} tag
- return jQuery.tmpl( jQuery.template( tmpl ), data, options, this );
- }
-
- function tiWrap( call, wrapped ) {
- // nested template, using {{wrap}} tag
- var options = call.options || {};
- options.wrapped = wrapped;
- // Apply the template, which may incorporate wrapped content,
- return jQuery.tmpl( jQuery.template( call.tmpl ), call.data, options, call.item );
- }
-
- function tiHtml( filter, textOnly ) {
- var wrapped = this._wrap;
- return jQuery.map(
- jQuery( jQuery.isArray( wrapped ) ? wrapped.join("") : wrapped ).filter( filter || "*" ),
- function(e) {
- return textOnly ?
- e.innerText || e.textContent :
- e.outerHTML || outerHtml(e);
- });
- }
-
- function tiUpdate() {
- var coll = this.nodes;
- jQuery.tmpl( null, null, null, this).insertBefore( coll[0] );
- jQuery( coll ).remove();
- }
-})( jQuery ); \ No newline at end of file
diff --git a/app/assets/javascripts/vendor/modernizr-2.0.6.min.js b/app/assets/javascripts/vendor/modernizr-2.0.6.min.js
deleted file mode 100755
index 52cd7e1..0000000
--- a/app/assets/javascripts/vendor/modernizr-2.0.6.min.js
+++ /dev/null
@@ -1,1116 +0,0 @@
-/*!
- * Modernizr v2.0.6
- * http://www.modernizr.com
- *
- * Copyright (c) 2009-2011 Faruk Ates, Paul Irish, Alex Sexton
- * Dual-licensed under the BSD or MIT licenses: www.modernizr.com/license/
- */
-
-/*
- * Modernizr tests which native CSS3 and HTML5 features are available in
- * the current UA and makes the results available to you in two ways:
- * as properties on a global Modernizr object, and as classes on the
- * <html> element. This information allows you to progressively enhance
- * your pages with a granular level of control over the experience.
- *
- * Modernizr has an optional (not included) conditional resource loader
- * called Modernizr.load(), based on Yepnope.js (yepnopejs.com).
- * To get a build that includes Modernizr.load(), as well as choosing
- * which tests to include, go to www.modernizr.com/download/
- *
- * Authors Faruk Ates, Paul Irish, Alex Sexton,
- * Contributors Ryan Seddon, Ben Alman
- */
-
-window.Modernizr = (function( window, document, undefined ) {
-
- var version = '2.0.6',
-
- Modernizr = {},
-
- // option for enabling the HTML classes to be added
- enableClasses = true,
-
- docElement = document.documentElement,
- docHead = document.head || document.getElementsByTagName('head')[0],
-
- /**
- * Create our "modernizr" element that we do most feature tests on.
- */
- mod = 'modernizr',
- modElem = document.createElement(mod),
- mStyle = modElem.style,
-
- /**
- * Create the input element for various Web Forms feature tests.
- */
- inputElem = document.createElement('input'),
-
- smile = ':)',
-
- toString = Object.prototype.toString,
-
- // List of property values to set for css tests. See ticket #21
- prefixes = ' -webkit- -moz- -o- -ms- -khtml- '.split(' '),
-
- // Following spec is to expose vendor-specific style properties as:
- // elem.style.WebkitBorderRadius
- // and the following would be incorrect:
- // elem.style.webkitBorderRadius
-
- // Webkit ghosts their properties in lowercase but Opera & Moz do not.
- // Microsoft foregoes prefixes entirely <= IE8, but appears to
- // use a lowercase `ms` instead of the correct `Ms` in IE9
-
- // More here: http://github.com/Modernizr/Modernizr/issues/issue/21
- domPrefixes = 'Webkit Moz O ms Khtml'.split(' '),
-
- ns = {'svg': 'http://www.w3.org/2000/svg'},
-
- tests = {},
- inputs = {},
- attrs = {},
-
- classes = [],
-
- featureName, // used in testing loop
-
-
- // Inject element with style element and some CSS rules
- injectElementWithStyles = function( rule, callback, nodes, testnames ) {
-
- var style, ret, node,
- div = document.createElement('div');
-
- if ( parseInt(nodes, 10) ) {
- // In order not to give false positives we create a node for each test
- // This also allows the method to scale for unspecified uses
- while ( nodes-- ) {
- node = document.createElement('div');
- node.id = testnames ? testnames[nodes] : mod + (nodes + 1);
- div.appendChild(node);
- }
- }
-
- // <style> elements in IE6-9 are considered 'NoScope' elements and therefore will be removed
- // when injected with innerHTML. To get around this you need to prepend the 'NoScope' element
- // with a 'scoped' element, in our case the soft-hyphen entity as it won't mess with our measurements.
- // http://msdn.microsoft.com/en-us/library/ms533897%28VS.85%29.aspx
- style = ['&shy;', '<style>', rule, '</style>'].join('');
- div.id = mod;
- div.innerHTML += style;
- docElement.appendChild(div);
-
- ret = callback(div, rule);
- div.parentNode.removeChild(div);
-
- return !!ret;
-
- },
-
-
- // adapted from matchMedia polyfill
- // by Scott Jehl and Paul Irish
- // gist.github.com/786768
- testMediaQuery = function( mq ) {
-
- if ( window.matchMedia ) {
- return matchMedia(mq).matches;
- }
-
- var bool;
-
- injectElementWithStyles('@media ' + mq + ' { #' + mod + ' { position: absolute; } }', function( node ) {
- bool = (window.getComputedStyle ?
- getComputedStyle(node, null) :
- node.currentStyle)['position'] == 'absolute';
- });
-
- return bool;
-
- },
-
-
- /**
- * isEventSupported determines if a given element supports the given event
- * function from http://yura.thinkweb2.com/isEventSupported/
- */
- isEventSupported = (function() {
-
- var TAGNAMES = {
- 'select': 'input', 'change': 'input',
- 'submit': 'form', 'reset': 'form',
- 'error': 'img', 'load': 'img', 'abort': 'img'
- };
-
- function isEventSupported( eventName, element ) {
-
- element = element || document.createElement(TAGNAMES[eventName] || 'div');
- eventName = 'on' + eventName;
-
- // When using `setAttribute`, IE skips "unload", WebKit skips "unload" and "resize", whereas `in` "catches" those
- var isSupported = eventName in element;
-
- if ( !isSupported ) {
- // If it has no `setAttribute` (i.e. doesn't implement Node interface), try generic element
- if ( !element.setAttribute ) {
- element = document.createElement('div');
- }
- if ( element.setAttribute && element.removeAttribute ) {
- element.setAttribute(eventName, '');
- isSupported = is(element[eventName], 'function');
-
- // If property was created, "remove it" (by setting value to `undefined`)
- if ( !is(element[eventName], undefined) ) {
- element[eventName] = undefined;
- }
- element.removeAttribute(eventName);
- }
- }
-
- element = null;
- return isSupported;
- }
- return isEventSupported;
- })();
-
- // hasOwnProperty shim by kangax needed for Safari 2.0 support
- var _hasOwnProperty = ({}).hasOwnProperty, hasOwnProperty;
- if ( !is(_hasOwnProperty, undefined) && !is(_hasOwnProperty.call, undefined) ) {
- hasOwnProperty = function (object, property) {
- return _hasOwnProperty.call(object, property);
- };
- }
- else {
- hasOwnProperty = function (object, property) { /* yes, this can give false positives/negatives, but most of the time we don't care about those */
- return ((property in object) && is(object.constructor.prototype[property], undefined));
- };
- }
-
- /**
- * setCss applies given styles to the Modernizr DOM node.
- */
- function setCss( str ) {
- mStyle.cssText = str;
- }
-
- /**
- * setCssAll extrapolates all vendor-specific css strings.
- */
- function setCssAll( str1, str2 ) {
- return setCss(prefixes.join(str1 + ';') + ( str2 || '' ));
- }
-
- /**
- * is returns a boolean for if typeof obj is exactly type.
- */
- function is( obj, type ) {
- return typeof obj === type;
- }
-
- /**
- * contains returns a boolean for if substr is found within str.
- */
- function contains( str, substr ) {
- return !!~('' + str).indexOf(substr);
- }
-
- /**
- * testProps is a generic CSS / DOM property test; if a browser supports
- * a certain property, it won't return undefined for it.
- * A supported CSS property returns empty string when its not yet set.
- */
- function testProps( props, prefixed ) {
- for ( var i in props ) {
- if ( mStyle[ props[i] ] !== undefined ) {
- return prefixed == 'pfx' ? props[i] : true;
- }
- }
- return false;
- }
-
- /**
- * testPropsAll tests a list of DOM properties we want to check against.
- * We specify literally ALL possible (known and/or likely) properties on
- * the element including the non-vendor prefixed one, for forward-
- * compatibility.
- */
- function testPropsAll( prop, prefixed ) {
-
- var ucProp = prop.charAt(0).toUpperCase() + prop.substr(1),
- props = (prop + ' ' + domPrefixes.join(ucProp + ' ') + ucProp).split(' ');
-
- return testProps(props, prefixed);
- }
-
- /**
- * testBundle tests a list of CSS features that require element and style injection.
- * By bundling them together we can reduce the need to touch the DOM multiple times.
- */
- /*>>testBundle*/
- var testBundle = (function( styles, tests ) {
- var style = styles.join(''),
- len = tests.length;
-
- injectElementWithStyles(style, function( node, rule ) {
- var style = document.styleSheets[document.styleSheets.length - 1],
- // IE8 will bork if you create a custom build that excludes both fontface and generatedcontent tests.
- // So we check for cssRules and that there is a rule available
- // More here: https://github.com/Modernizr/Modernizr/issues/288 & https://github.com/Modernizr/Modernizr/issues/293
- cssText = style.cssRules && style.cssRules[0] ? style.cssRules[0].cssText : style.cssText || "",
- children = node.childNodes, hash = {};
-
- while ( len-- ) {
- hash[children[len].id] = children[len];
- }
-
- /*>>touch*/ Modernizr['touch'] = ('ontouchstart' in window) || hash['touch'].offsetTop === 9; /*>>touch*/
- /*>>csstransforms3d*/ Modernizr['csstransforms3d'] = hash['csstransforms3d'].offsetLeft === 9; /*>>csstransforms3d*/
- /*>>generatedcontent*/Modernizr['generatedcontent'] = hash['generatedcontent'].offsetHeight >= 1; /*>>generatedcontent*/
- /*>>fontface*/ Modernizr['fontface'] = /src/i.test(cssText) &&
- cssText.indexOf(rule.split(' ')[0]) === 0; /*>>fontface*/
- }, len, tests);
-
- })([
- // Pass in styles to be injected into document
- /*>>fontface*/ '@font-face {font-family:"font";src:url("https://")}' /*>>fontface*/
-
- /*>>touch*/ ,['@media (',prefixes.join('touch-enabled),('),mod,')',
- '{#touch{top:9px;position:absolute}}'].join('') /*>>touch*/
-
- /*>>csstransforms3d*/ ,['@media (',prefixes.join('transform-3d),('),mod,')',
- '{#csstransforms3d{left:9px;position:absolute}}'].join('')/*>>csstransforms3d*/
-
- /*>>generatedcontent*/,['#generatedcontent:after{content:"',smile,'";visibility:hidden}'].join('') /*>>generatedcontent*/
- ],
- [
- /*>>fontface*/ 'fontface' /*>>fontface*/
- /*>>touch*/ ,'touch' /*>>touch*/
- /*>>csstransforms3d*/ ,'csstransforms3d' /*>>csstransforms3d*/
- /*>>generatedcontent*/,'generatedcontent' /*>>generatedcontent*/
-
- ]);/*>>testBundle*/
-
-
- /**
- * Tests
- * -----
- */
-
- tests['flexbox'] = function() {
- /**
- * setPrefixedValueCSS sets the property of a specified element
- * adding vendor prefixes to the VALUE of the property.
- * @param {Element} element
- * @param {string} property The property name. This will not be prefixed.
- * @param {string} value The value of the property. This WILL be prefixed.
- * @param {string=} extra Additional CSS to append unmodified to the end of
- * the CSS string.
- */
- function setPrefixedValueCSS( element, property, value, extra ) {
- property += ':';
- element.style.cssText = (property + prefixes.join(value + ';' + property)).slice(0, -property.length) + (extra || '');
- }
-
- /**
- * setPrefixedPropertyCSS sets the property of a specified element
- * adding vendor prefixes to the NAME of the property.
- * @param {Element} element
- * @param {string} property The property name. This WILL be prefixed.
- * @param {string} value The value of the property. This will not be prefixed.
- * @param {string=} extra Additional CSS to append unmodified to the end of
- * the CSS string.
- */
- function setPrefixedPropertyCSS( element, property, value, extra ) {
- element.style.cssText = prefixes.join(property + ':' + value + ';') + (extra || '');
- }
-
- var c = document.createElement('div'),
- elem = document.createElement('div');
-
- setPrefixedValueCSS(c, 'display', 'box', 'width:42px;padding:0;');
- setPrefixedPropertyCSS(elem, 'box-flex', '1', 'width:10px;');
-
- c.appendChild(elem);
- docElement.appendChild(c);
-
- var ret = elem.offsetWidth === 42;
-
- c.removeChild(elem);
- docElement.removeChild(c);
-
- return ret;
- };
-
- // On the S60 and BB Storm, getContext exists, but always returns undefined
- // http://github.com/Modernizr/Modernizr/issues/issue/97/
-
- tests['canvas'] = function() {
- var elem = document.createElement('canvas');
- return !!(elem.getContext && elem.getContext('2d'));
- };
-
- tests['canvastext'] = function() {
- return !!(Modernizr['canvas'] && is(document.createElement('canvas').getContext('2d').fillText, 'function'));
- };
-
- // This WebGL test may false positive.
- // But really it's quite impossible to know whether webgl will succeed until after you create the context.
- // You might have hardware that can support a 100x100 webgl canvas, but will not support a 1000x1000 webgl
- // canvas. So this feature inference is weak, but intentionally so.
-
- // It is known to false positive in FF4 with certain hardware and the iPad 2.
-
- tests['webgl'] = function() {
- return !!window.WebGLRenderingContext;
- };
-
- /*
- * The Modernizr.touch test only indicates if the browser supports
- * touch events, which does not necessarily reflect a touchscreen
- * device, as evidenced by tablets running Windows 7 or, alas,
- * the Palm Pre / WebOS (touch) phones.
- *
- * Additionally, Chrome (desktop) used to lie about its support on this,
- * but that has since been rectified: http://crbug.com/36415
- *
- * We also test for Firefox 4 Multitouch Support.
- *
- * For more info, see: http://modernizr.github.com/Modernizr/touch.html
- */
-
- tests['touch'] = function() {
- return Modernizr['touch'];
- };
-
- /**
- * geolocation tests for the new Geolocation API specification.
- * This test is a standards compliant-only test; for more complete
- * testing, including a Google Gears fallback, please see:
- * http://code.google.com/p/geo-location-javascript/
- * or view a fallback solution using google's geo API:
- * http://gist.github.com/366184
- */
- tests['geolocation'] = function() {
- return !!navigator.geolocation;
- };
-
- // Per 1.6:
- // This used to be Modernizr.crosswindowmessaging but the longer
- // name has been deprecated in favor of a shorter and property-matching one.
- // The old API is still available in 1.6, but as of 2.0 will throw a warning,
- // and in the first release thereafter disappear entirely.
- tests['postmessage'] = function() {
- return !!window.postMessage;
- };
-
- // Web SQL database detection is tricky:
-
- // In chrome incognito mode, openDatabase is truthy, but using it will
- // throw an exception: http://crbug.com/42380
- // We can create a dummy database, but there is no way to delete it afterwards.
-
- // Meanwhile, Safari users can get prompted on any database creation.
- // If they do, any page with Modernizr will give them a prompt:
- // http://github.com/Modernizr/Modernizr/issues/closed#issue/113
-
- // We have chosen to allow the Chrome incognito false positive, so that Modernizr
- // doesn't litter the web with these test databases. As a developer, you'll have
- // to account for this gotcha yourself.
- tests['websqldatabase'] = function() {
- var result = !!window.openDatabase;
- /* if (result){
- try {
- result = !!openDatabase( mod + "testdb", "1.0", mod + "testdb", 2e4);
- } catch(e) {
- }
- } */
- return result;
- };
-
- // Vendors had inconsistent prefixing with the experimental Indexed DB:
- // - Webkit's implementation is accessible through webkitIndexedDB
- // - Firefox shipped moz_indexedDB before FF4b9, but since then has been mozIndexedDB
- // For speed, we don't test the legacy (and beta-only) indexedDB
- tests['indexedDB'] = function() {
- for ( var i = -1, len = domPrefixes.length; ++i < len; ){
- if ( window[domPrefixes[i].toLowerCase() + 'IndexedDB'] ){
- return true;
- }
- }
- return !!window.indexedDB;
- };
-
- // documentMode logic from YUI to filter out IE8 Compat Mode
- // which false positives.
- tests['hashchange'] = function() {
- return isEventSupported('hashchange', window) && (document.documentMode === undefined || document.documentMode > 7);
- };
-
- // Per 1.6:
- // This used to be Modernizr.historymanagement but the longer
- // name has been deprecated in favor of a shorter and property-matching one.
- // The old API is still available in 1.6, but as of 2.0 will throw a warning,
- // and in the first release thereafter disappear entirely.
- tests['history'] = function() {
- return !!(window.history && history.pushState);
- };
-
- tests['draganddrop'] = function() {
- return isEventSupported('dragstart') && isEventSupported('drop');
- };
-
- // Mozilla is targeting to land MozWebSocket for FF6
- // bugzil.la/659324
- tests['websockets'] = function() {
- for ( var i = -1, len = domPrefixes.length; ++i < len; ){
- if ( window[domPrefixes[i] + 'WebSocket'] ){
- return true;
- }
- }
- return 'WebSocket' in window;
- };
-
-
- // http://css-tricks.com/rgba-browser-support/
- tests['rgba'] = function() {
- // Set an rgba() color and check the returned value
-
- setCss('background-color:rgba(150,255,150,.5)');
-
- return contains(mStyle.backgroundColor, 'rgba');
- };
-
- tests['hsla'] = function() {
- // Same as rgba(), in fact, browsers re-map hsla() to rgba() internally,
- // except IE9 who retains it as hsla
-
- setCss('background-color:hsla(120,40%,100%,.5)');
-
- return contains(mStyle.backgroundColor, 'rgba') || contains(mStyle.backgroundColor, 'hsla');
- };
-
- tests['multiplebgs'] = function() {
- // Setting multiple images AND a color on the background shorthand property
- // and then querying the style.background property value for the number of
- // occurrences of "url(" is a reliable method for detecting ACTUAL support for this!
-
- setCss('background:url(https://),url(https://),red url(https://)');
-
- // If the UA supports multiple backgrounds, there should be three occurrences
- // of the string "url(" in the return value for elemStyle.background
-
- return /(url\s*\(.*?){3}/.test(mStyle.background);
- };
-
-
- // In testing support for a given CSS property, it's legit to test:
- // `elem.style[styleName] !== undefined`
- // If the property is supported it will return an empty string,
- // if unsupported it will return undefined.
-
- // We'll take advantage of this quick test and skip setting a style
- // on our modernizr element, but instead just testing undefined vs
- // empty string.
-
-
- tests['backgroundsize'] = function() {
- return testPropsAll('backgroundSize');
- };
-
- tests['borderimage'] = function() {
- return testPropsAll('borderImage');
- };
-
-
- // Super comprehensive table about all the unique implementations of
- // border-radius: http://muddledramblings.com/table-of-css3-border-radius-compliance
-
- tests['borderradius'] = function() {
- return testPropsAll('borderRadius');
- };
-
- // WebOS unfortunately false positives on this test.
- tests['boxshadow'] = function() {
- return testPropsAll('boxShadow');
- };
-
- // FF3.0 will false positive on this test
- tests['textshadow'] = function() {
- return document.createElement('div').style.textShadow === '';
- };
-
-
- tests['opacity'] = function() {
- // Browsers that actually have CSS Opacity implemented have done so
- // according to spec, which means their return values are within the
- // range of [0.0,1.0] - including the leading zero.
-
- setCssAll('opacity:.55');
-
- // The non-literal . in this regex is intentional:
- // German Chrome returns this value as 0,55
- // https://github.com/Modernizr/Modernizr/issues/#issue/59/comment/516632
- return /^0.55$/.test(mStyle.opacity);
- };
-
-
- tests['cssanimations'] = function() {
- return testPropsAll('animationName');
- };
-
-
- tests['csscolumns'] = function() {
- return testPropsAll('columnCount');
- };
-
-
- tests['cssgradients'] = function() {
- /**
- * For CSS Gradients syntax, please see:
- * http://webkit.org/blog/175/introducing-css-gradients/
- * https://developer.mozilla.org/en/CSS/-moz-linear-gradient
- * https://developer.mozilla.org/en/CSS/-moz-radial-gradient
- * http://dev.w3.org/csswg/css3-images/#gradients-
- */
-
- var str1 = 'background-image:',
- str2 = 'gradient(linear,left top,right bottom,from(#9f9),to(white));',
- str3 = 'linear-gradient(left top,#9f9, white);';
-
- setCss(
- (str1 + prefixes.join(str2 + str1) + prefixes.join(str3 + str1)).slice(0, -str1.length)
- );
-
- return contains(mStyle.backgroundImage, 'gradient');
- };
-
-
- tests['cssreflections'] = function() {
- return testPropsAll('boxReflect');
- };
-
-
- tests['csstransforms'] = function() {
- return !!testProps(['transformProperty', 'WebkitTransform', 'MozTransform', 'OTransform', 'msTransform']);
- };
-
-
- tests['csstransforms3d'] = function() {
-
- var ret = !!testProps(['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective']);
-
- // Webkit’s 3D transforms are passed off to the browser's own graphics renderer.
- // It works fine in Safari on Leopard and Snow Leopard, but not in Chrome in
- // some conditions. As a result, Webkit typically recognizes the syntax but
- // will sometimes throw a false positive, thus we must do a more thorough check:
- if ( ret && 'webkitPerspective' in docElement.style ) {
-
- // Webkit allows this media query to succeed only if the feature is enabled.
- // `@media (transform-3d),(-o-transform-3d),(-moz-transform-3d),(-ms-transform-3d),(-webkit-transform-3d),(modernizr){ ... }`
- ret = Modernizr['csstransforms3d'];
- }
- return ret;
- };
-
-
- tests['csstransitions'] = function() {
- return testPropsAll('transitionProperty');
- };
-
-
- /*>>fontface*/
- // @font-face detection routine by Diego Perini
- // http://javascript.nwbox.com/CSSSupport/
- tests['fontface'] = function() {
- return Modernizr['fontface'];
- };
- /*>>fontface*/
-
- // CSS generated content detection
- tests['generatedcontent'] = function() {
- return Modernizr['generatedcontent'];
- };
-
-
-
- // These tests evaluate support of the video/audio elements, as well as
- // testing what types of content they support.
- //
- // We're using the Boolean constructor here, so that we can extend the value
- // e.g. Modernizr.video // true
- // Modernizr.video.ogg // 'probably'
- //
- // Codec values from : http://github.com/NielsLeenheer/html5test/blob/9106a8/index.html#L845
- // thx to NielsLeenheer and zcorpan
-
- // Note: in FF 3.5.1 and 3.5.0, "no" was a return value instead of empty string.
- // Modernizr does not normalize for that.
-
- tests['video'] = function() {
- var elem = document.createElement('video'),
- bool = false;
-
- // IE9 Running on Windows Server SKU can cause an exception to be thrown, bug #224
- try {
- if ( bool = !!elem.canPlayType ) {
- bool = new Boolean(bool);
- bool.ogg = elem.canPlayType('video/ogg; codecs="theora"');
-
- // Workaround required for IE9, which doesn't report video support without audio codec specified.
- // bug 599718 @ msft connect
- var h264 = 'video/mp4; codecs="avc1.42E01E';
- bool.h264 = elem.canPlayType(h264 + '"') || elem.canPlayType(h264 + ', mp4a.40.2"');
-
- bool.webm = elem.canPlayType('video/webm; codecs="vp8, vorbis"');
- }
-
- } catch(e) { }
-
- return bool;
- };
-
- tests['audio'] = function() {
- var elem = document.createElement('audio'),
- bool = false;
-
- try {
- if ( bool = !!elem.canPlayType ) {
- bool = new Boolean(bool);
- bool.ogg = elem.canPlayType('audio/ogg; codecs="vorbis"');
- bool.mp3 = elem.canPlayType('audio/mpeg;');
-
- // Mimetypes accepted:
- // https://developer.mozilla.org/En/Media_formats_supported_by_the_audio_and_video_elements
- // http://bit.ly/iphoneoscodecs
- bool.wav = elem.canPlayType('audio/wav; codecs="1"');
- bool.m4a = elem.canPlayType('audio/x-m4a;') || elem.canPlayType('audio/aac;');
- }
- } catch(e) { }
-
- return bool;
- };
-
-
- // Firefox has made these tests rather unfun.
-
- // In FF4, if disabled, window.localStorage should === null.
-
- // Normally, we could not test that directly and need to do a
- // `('localStorage' in window) && ` test first because otherwise Firefox will
- // throw http://bugzil.la/365772 if cookies are disabled
-
- // However, in Firefox 4 betas, if dom.storage.enabled == false, just mentioning
- // the property will throw an exception. http://bugzil.la/599479
- // This looks to be fixed for FF4 Final.
-
- // Because we are forced to try/catch this, we'll go aggressive.
-
- // FWIW: IE8 Compat mode supports these features completely:
- // http://www.quirksmode.org/dom/html5.html
- // But IE8 doesn't support either with local files
-
- tests['localstorage'] = function() {
- try {
- return !!localStorage.getItem;
- } catch(e) {
- return false;
- }
- };
-
- tests['sessionstorage'] = function() {
- try {
- return !!sessionStorage.getItem;
- } catch(e){
- return false;
- }
- };
-
-
- tests['webworkers'] = function() {
- return !!window.Worker;
- };
-
-
- tests['applicationcache'] = function() {
- return !!window.applicationCache;
- };
-
-
- // Thanks to Erik Dahlstrom
- tests['svg'] = function() {
- return !!document.createElementNS && !!document.createElementNS(ns.svg, 'svg').createSVGRect;
- };
-
- // specifically for SVG inline in HTML, not within XHTML
- // test page: paulirish.com/demo/inline-svg
- tests['inlinesvg'] = function() {
- var div = document.createElement('div');
- div.innerHTML = '<svg/>';
- return (div.firstChild && div.firstChild.namespaceURI) == ns.svg;
- };
-
- // Thanks to F1lt3r and lucideer, ticket #35
- tests['smil'] = function() {
- return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'animate')));
- };
-
- tests['svgclippaths'] = function() {
- // Possibly returns a false positive in Safari 3.2?
- return !!document.createElementNS && /SVG/.test(toString.call(document.createElementNS(ns.svg, 'clipPath')));
- };
-
- // input features and input types go directly onto the ret object, bypassing the tests loop.
- // Hold this guy to execute in a moment.
- function webforms() {
- // Run through HTML5's new input attributes to see if the UA understands any.
- // We're using f which is the <input> element created early on
- // Mike Taylr has created a comprehensive resource for testing these attributes
- // when applied to all input types:
- // http://miketaylr.com/code/input-type-attr.html
- // spec: http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html#input-type-attr-summary
-
- // Only input placeholder is tested while textarea's placeholder is not.
- // Currently Safari 4 and Opera 11 have support only for the input placeholder
- // Both tests are available in feature-detects/forms-placeholder.js
- Modernizr['input'] = (function( props ) {
- for ( var i = 0, len = props.length; i < len; i++ ) {
- attrs[ props[i] ] = !!(props[i] in inputElem);
- }
- return attrs;
- })('autocomplete autofocus list placeholder max min multiple pattern required step'.split(' '));
-
- // Run through HTML5's new input types to see if the UA understands any.
- // This is put behind the tests runloop because it doesn't return a
- // true/false like all the other tests; instead, it returns an object
- // containing each input type with its corresponding true/false value
-
- // Big thanks to @miketaylr for the html5 forms expertise. http://miketaylr.com/
- Modernizr['inputtypes'] = (function(props) {
-
- for ( var i = 0, bool, inputElemType, defaultView, len = props.length; i < len; i++ ) {
-
- inputElem.setAttribute('type', inputElemType = props[i]);
- bool = inputElem.type !== 'text';
-
- // We first check to see if the type we give it sticks..
- // If the type does, we feed it a textual value, which shouldn't be valid.
- // If the value doesn't stick, we know there's input sanitization which infers a custom UI
- if ( bool ) {
-
- inputElem.value = smile;
- inputElem.style.cssText = 'position:absolute;visibility:hidden;';
-
- if ( /^range$/.test(inputElemType) && inputElem.style.WebkitAppearance !== undefined ) {
-
- docElement.appendChild(inputElem);
- defaultView = document.defaultView;
-
- // Safari 2-4 allows the smiley as a value, despite making a slider
- bool = defaultView.getComputedStyle &&
- defaultView.getComputedStyle(inputElem, null).WebkitAppearance !== 'textfield' &&
- // Mobile android web browser has false positive, so must
- // check the height to see if the widget is actually there.
- (inputElem.offsetHeight !== 0);
-
- docElement.removeChild(inputElem);
-
- } else if ( /^(search|tel)$/.test(inputElemType) ){
- // Spec doesnt define any special parsing or detectable UI
- // behaviors so we pass these through as true
-
- // Interestingly, opera fails the earlier test, so it doesn't
- // even make it here.
-
- } else if ( /^(url|email)$/.test(inputElemType) ) {
- // Real url and email support comes with prebaked validation.
- bool = inputElem.checkValidity && inputElem.checkValidity() === false;
-
- } else if ( /^color$/.test(inputElemType) ) {
- // chuck into DOM and force reflow for Opera bug in 11.00
- // github.com/Modernizr/Modernizr/issues#issue/159
- docElement.appendChild(inputElem);
- docElement.offsetWidth;
- bool = inputElem.value != smile;
- docElement.removeChild(inputElem);
-
- } else {
- // If the upgraded input compontent rejects the :) text, we got a winner
- bool = inputElem.value != smile;
- }
- }
-
- inputs[ props[i] ] = !!bool;
- }
- return inputs;
- })('search tel url email datetime date month week time datetime-local number range color'.split(' '));
- }
-
-
- // End of test definitions
- // -----------------------
-
-
-
- // Run through all tests and detect their support in the current UA.
- // todo: hypothetically we could be doing an array of tests and use a basic loop here.
- for ( var feature in tests ) {
- if ( hasOwnProperty(tests, feature) ) {
- // run the test, throw the return value into the Modernizr,
- // then based on that boolean, define an appropriate className
- // and push it into an array of classes we'll join later.
- featureName = feature.toLowerCase();
- Modernizr[featureName] = tests[feature]();
-
- classes.push((Modernizr[featureName] ? '' : 'no-') + featureName);
- }
- }
-
- // input tests need to run.
- Modernizr.input || webforms();
-
-
- /**
- * addTest allows the user to define their own feature tests
- * the result will be added onto the Modernizr object,
- * as well as an appropriate className set on the html element
- *
- * @param feature - String naming the feature
- * @param test - Function returning true if feature is supported, false if not
- */
- Modernizr.addTest = function ( feature, test ) {
- if ( typeof feature == "object" ) {
- for ( var key in feature ) {
- if ( hasOwnProperty( feature, key ) ) {
- Modernizr.addTest( key, feature[ key ] );
- }
- }
- } else {
-
- feature = feature.toLowerCase();
-
- if ( Modernizr[feature] !== undefined ) {
- // we're going to quit if you're trying to overwrite an existing test
- // if we were to allow it, we'd do this:
- // var re = new RegExp("\\b(no-)?" + feature + "\\b");
- // docElement.className = docElement.className.replace( re, '' );
- // but, no rly, stuff 'em.
- return;
- }
-
- test = typeof test == "boolean" ? test : !!test();
-
- docElement.className += ' ' + (test ? '' : 'no-') + feature;
- Modernizr[feature] = test;
-
- }
-
- return Modernizr; // allow chaining.
- };
-
-
- // Reset modElem.cssText to nothing to reduce memory footprint.
- setCss('');
- modElem = inputElem = null;
-
- //>>BEGIN IEPP
- // Enable HTML 5 elements for styling (and printing) in IE.
- if ( window.attachEvent && (function(){ var elem = document.createElement('div');
- elem.innerHTML = '<elem></elem>';
- return elem.childNodes.length !== 1; })() ) {
-
- // iepp v2 by @jon_neal & afarkas : github.com/aFarkas/iepp/
- (function(win, doc) {
- win.iepp = win.iepp || {};
- var iepp = win.iepp,
- elems = iepp.html5elements || 'abbr|article|aside|audio|canvas|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video',
- elemsArr = elems.split('|'),
- elemsArrLen = elemsArr.length,
- elemRegExp = new RegExp('(^|\\s)('+elems+')', 'gi'),
- tagRegExp = new RegExp('<(\/*)('+elems+')', 'gi'),
- filterReg = /^\s*[\{\}]\s*$/,
- ruleRegExp = new RegExp('(^|[^\\n]*?\\s)('+elems+')([^\\n]*)({[\\n\\w\\W]*?})', 'gi'),
- docFrag = doc.createDocumentFragment(),
- html = doc.documentElement,
- head = html.firstChild,
- bodyElem = doc.createElement('body'),
- styleElem = doc.createElement('style'),
- printMedias = /print|all/,
- body;
- function shim(doc) {
- var a = -1;
- while (++a < elemsArrLen)
- // Use createElement so IE allows HTML5-named elements in a document
- doc.createElement(elemsArr[a]);
- }
-
- iepp.getCSS = function(styleSheetList, mediaType) {
- if(styleSheetList+'' === undefined){return '';}
- var a = -1,
- len = styleSheetList.length,
- styleSheet,
- cssTextArr = [];
- while (++a < len) {
- styleSheet = styleSheetList[a];
- //currently no test for disabled/alternate stylesheets
- if(styleSheet.disabled){continue;}
- mediaType = styleSheet.media || mediaType;
- // Get css from all non-screen stylesheets and their imports
- if (printMedias.test(mediaType)) cssTextArr.push(iepp.getCSS(styleSheet.imports, mediaType), styleSheet.cssText);
- //reset mediaType to all with every new *not imported* stylesheet
- mediaType = 'all';
- }
- return cssTextArr.join('');
- };
-
- iepp.parseCSS = function(cssText) {
- var cssTextArr = [],
- rule;
- while ((rule = ruleRegExp.exec(cssText)) != null){
- // Replace all html5 element references with iepp substitute classnames
- cssTextArr.push(( (filterReg.exec(rule[1]) ? '\n' : rule[1]) +rule[2]+rule[3]).replace(elemRegExp, '$1.iepp_$2')+rule[4]);
- }
- return cssTextArr.join('\n');
- };
-
- iepp.writeHTML = function() {
- var a = -1;
- body = body || doc.body;
- while (++a < elemsArrLen) {
- var nodeList = doc.getElementsByTagName(elemsArr[a]),
- nodeListLen = nodeList.length,
- b = -1;
- while (++b < nodeListLen)
- if (nodeList[b].className.indexOf('iepp_') < 0)
- // Append iepp substitute classnames to all html5 elements
- nodeList[b].className += ' iepp_'+elemsArr[a];
- }
- docFrag.appendChild(body);
- html.appendChild(bodyElem);
- // Write iepp substitute print-safe document
- bodyElem.className = body.className;
- bodyElem.id = body.id;
- // Replace HTML5 elements with <font> which is print-safe and shouldn't conflict since it isn't part of html5
- bodyElem.innerHTML = body.innerHTML.replace(tagRegExp, '<$1font');
- };
-
-
- iepp._beforePrint = function() {
- // Write iepp custom print CSS
- styleElem.styleSheet.cssText = iepp.parseCSS(iepp.getCSS(doc.styleSheets, 'all'));
- iepp.writeHTML();
- };
-
- iepp.restoreHTML = function(){
- // Undo everything done in onbeforeprint
- bodyElem.innerHTML = '';
- html.removeChild(bodyElem);
- html.appendChild(body);
- };
-
- iepp._afterPrint = function(){
- // Undo everything done in onbeforeprint
- iepp.restoreHTML();
- styleElem.styleSheet.cssText = '';
- };
-
-
-
- // Shim the document and iepp fragment
- shim(doc);
- shim(docFrag);
-
- //
- if(iepp.disablePP){return;}
-
- // Add iepp custom print style element
- head.insertBefore(styleElem, head.firstChild);
- styleElem.media = 'print';
- styleElem.className = 'iepp-printshim';
- win.attachEvent(
- 'onbeforeprint',
- iepp._beforePrint
- );
- win.attachEvent(
- 'onafterprint',
- iepp._afterPrint
- );
- })(window, document);
- }
- //>>END IEPP
-
- // Assign private properties to the return object with prefix
- Modernizr._version = version;
-
- // expose these for the plugin API. Look in the source for how to join() them against your input
- Modernizr._prefixes = prefixes;
- Modernizr._domPrefixes = domPrefixes;
-
- // Modernizr.mq tests a given media query, live against the current state of the window
- // A few important notes:
- // * If a browser does not support media queries at all (eg. oldIE) the mq() will always return false
- // * A max-width or orientation query will be evaluated against the current state, which may change later.
- // * You must specify values. Eg. If you are testing support for the min-width media query use:
- // Modernizr.mq('(min-width:0)')
- // usage:
- // Modernizr.mq('only screen and (max-width:768)')
- Modernizr.mq = testMediaQuery;
-
- // Modernizr.hasEvent() detects support for a given event, with an optional element to test on
- // Modernizr.hasEvent('gesturestart', elem)
- Modernizr.hasEvent = isEventSupported;
-
- // Modernizr.testProp() investigates whether a given style property is recognized
- // Note that the property names must be provided in the camelCase variant.
- // Modernizr.testProp('pointerEvents')
- Modernizr.testProp = function(prop){
- return testProps([prop]);
- };
-
- // Modernizr.testAllProps() investigates whether a given style property,
- // or any of its vendor-prefixed variants, is recognized
- // Note that the property names must be provided in the camelCase variant.
- // Modernizr.testAllProps('boxSizing')
- Modernizr.testAllProps = testPropsAll;
-
-
-
- // Modernizr.testStyles() allows you to add custom styles to the document and test an element afterwards
- // Modernizr.testStyles('#modernizr { position:absolute }', function(elem, rule){ ... })
- Modernizr.testStyles = injectElementWithStyles;
-
-
- // Modernizr.prefixed() returns the prefixed or nonprefixed property name variant of your input
- // Modernizr.prefixed('boxSizing') // 'MozBoxSizing'
-
- // Properties must be passed as dom-style camelcase, rather than `box-sizing` hypentated style.
- // Return values will also be the camelCase variant, if you need to translate that to hypenated style use:
- //
- // str.replace(/([A-Z])/g, function(str,m1){ return '-' + m1.toLowerCase(); }).replace(/^ms-/,'-ms-');
-
- // If you're trying to ascertain which transition end event to bind to, you might do something like...
- //
- // var transEndEventNames = {
- // 'WebkitTransition' : 'webkitTransitionEnd',
- // 'MozTransition' : 'transitionend',
- // 'OTransition' : 'oTransitionEnd',
- // 'msTransition' : 'msTransitionEnd', // maybe?
- // 'transition' : 'transitionEnd'
- // },
- // transEndEventName = transEndEventNames[ Modernizr.prefixed('transition') ];
-
- Modernizr.prefixed = function(prop){
- return testPropsAll(prop, 'pfx');
- };
-
-
-
- // Remove "no-js" class from <html> element, if it exists:
- docElement.className = docElement.className.replace(/\bno-js\b/, '')
-
- // Add the new classes to the <html> element.
- + (enableClasses ? ' js ' + classes.join(' ') : '');
-
- return Modernizr;
-
-})(this, this.document); \ No newline at end of file
diff --git a/app/assets/stylesheets/app/layouts/_app.scss b/app/assets/stylesheets/app/layouts/_app.scss
deleted file mode 100644
index abbe8b1..0000000
--- a/app/assets/stylesheets/app/layouts/_app.scss
+++ /dev/null
@@ -1,24 +0,0 @@
-// Application Layout
-// ----------------------------------------
-// TODO: This generates huge selectors..
-.app {
-
- #main {
- @include center-container(1000px, 0, 0 8px);
- @include clearfix;
- @include debug(gray);
- }
-
- $sidebar: 215px;
- $content: 758px;
-
- .container {
- & > aside {
- @include float(left, $sidebar, green);
- }
-
- & > .content {
- @include float(right, $content, blue);
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/layouts/_conference.scss b/app/assets/stylesheets/app/layouts/_conference.scss
deleted file mode 100644
index 18fb232..0000000
--- a/app/assets/stylesheets/app/layouts/_conference.scss
+++ /dev/null
@@ -1,136 +0,0 @@
-// Conference
-// ----------------------------------------
-
-// The Usual Box with Mute, Cross
-.actor {
- @include clearfix;
- @include gradient(#FDFDFD, #EFEFEF);
- @include size(auto, 50px,6px, 1px 0 1px 0);
- border-bottom:1px solid #E3E3E8;
- border-top:1px solid #FFF;
- img {
- @extend .ext-bradius-inner;
- float:left;
- margin-right:6px;
- }
- .info {
- .name {
- display:block;
- font-size:size(15px);
- width:188px;
- }
- .status {
- color:#818181;
- }
- float:left;
- }
- .voice-actions {
- float:right;
- }
-}
-
-// Audio Controls.
-.voice-actions {
- padding:10px 0;
- text-align:right;
- width:100px;
- .make.speaker {
- @include image-replace('icons/microphone-16x.png');
- display:inline-block;
- }
- .make.listener {
- @include image-replace('icons/headphones-16x.png');
- display:inline-block;
- }
-
- .voice {
- &.muted {
- @include image-replace('icons/mute-16x.png');
- display:inline-block;
- }
- &.unmuted {
- @include image-replace('icons/unmute-16x.png');
- display:inline-block;
- }
- }
- .remove {
- @include image-replace('icons/cross-16x.png');
- display:inline-block;
- }
- a {
- margin:0 5px;
- opacity:0.6;
- &:hover { opacity:1.0;}
- }
-}
-
-
-.conference {
- @include pie-clearfix();
- .panel {
- @include box-shadow(1px 1px 0px #FFF inset, 1px 1px 1px #EDEDED);
- background:#F7F7F7;
- border:1px solid #E3E3E8;
- float:left;
- margin: 0 10px;
- width: 303px;
- &.speakers {
- header { @include gradient(#FFF, #F3F3DE); }
- h3 { background:transparent image-url('icons/microphone-32x.png') left top no-repeat; }
- }
- &.listeners {
- header { @include gradient(#FFF, #DCEAF2); }
- h3 { background:transparent image-url('icons/headphones-32x.png') left top no-repeat; }
- }
- &.log {
- header { @include gradient(#FFF, #E7E7E7); }
- h3 { background:transparent image-url('icons/clock-32x.png') left top no-repeat; }
- }
- }
- .first { margin-left:0;}
- .last { margin-right:0;}
- header {
- @include box-shadow(1px 1px 0px #FFF inset, 0px 1px 0px #FFF);
- border-bottom:1px solid #E3E3E8;
- padding:10px;
- }
- h3 {
- font-size:size(24px);
- font-weight:normal;
- margin:0;
- opacity:0.8;
- padding:2px 2px 2px 43px;
- }
- .message {
- @include gradient( #EEEEEE, #fff);
- border-bottom:1px solid #E3E3E8;
- padding:10px;
- input {
- @include input-effects;
- @include size(283px, auto, 5px, 1px solid #E3E3E8 );
- color:#696969;
- }
- }
- .actors, .messages {
- height:290px; // This should be X times the amount of items
- overflow:auto;
- }
-}
-
-.log {
- .messages {
- color:#484848;
- div {
- background:#FFF;
- border-bottom:1px solid #E3E3E8;
- border-top:1px solid #FFF;
- padding:5px 10px;
- }
- .status {
- background:#F5F5F5;
- }
- .name {
- font-weight:bold;
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/layouts/_phone-book-entry.scss b/app/assets/stylesheets/app/layouts/_phone-book-entry.scss
deleted file mode 100644
index f9e2345..0000000
--- a/app/assets/stylesheets/app/layouts/_phone-book-entry.scss
+++ /dev/null
@@ -1,176 +0,0 @@
-// Phone Book Entry Show
-// ----------------------------------------
-// Icons: http://www.iconfinder.com/search/?q=iconset%3Acc_mono_icon_set
-//http://www.iconfinder.com/search/?q=iconset%3AHelveticons_Social
-section.phone-book-entry {
- @include clearfix;
- a {
- @include link-colors(#49494D, $link-color);
- }
- .sidebar {
- @include size(220px, auto, none, 0 1px 0 0);
- border-right:1px solid #E3E3E8;
- float:left;
- }
- .content {
- float:right;
- width:716px;
-
- }
-
- .username {
- font-size: 46px;
- font-weight:normal;
- margin: 0 0 10px 0;
- }
- .personal {
- margin-top:5px;
- span {
- margin-right:10px;
- padding-left:22px;
- }
- .nickname {
- background:transparent image-url('icons/user-16x.png') left 1px no-repeat;
- }
- .birthday {
- background:transparent image-url('icons/star-16x.png') left -1px no-repeat;;
- }
- }
-
- .work {
- font-size: 18px;
- }
-
- .tags {
- background:transparent image-url('icons/tag-16x.png') left 0px no-repeat;
- margin-top:10px;
- padding-left:22px;
- }
-
-
- .activity {
- & > h2 {
- font-size: 27px;
- font-weight: normal;
- }
- textarea {
- border-color: #E3E3E8;
- height: 15px;
- padding: 12px;
- width: 689px;
- }
- .entry {
- @include clearfix;
- background-position: 12px 9px;
- border-bottom: 1px solid #E3E3E8;
- font-size: 16px;
-
- padding: 12px 0px 15px 55px;
- .motive {
-
- display: block;
- float: left;
- line-height: 25px;
- width: 529px;
-
- }
- .timestamp {
- color: #929298;
- float: right;
- font-size: 12px;
- line-height: 26px;
- }
- }
- }
-
-
- // Icons
- .home {
- background:transparent image-url('icons/house-32x.png') left 2px no-repeat;
- }
- .office {
- background:transparent image-url('icons/suitcase-32x.png') left 2px no-repeat;
- }
- .cellphone {
- background:transparent image-url('icons/phone-mobile-32x.png') left 2px no-repeat;
- }
- .phone {
- background:transparent image-url('icons/phone-up-32x.png') left 2px no-repeat;
- }
- .phone-down {
- background:transparent image-url('icons/phone-down-32x.png') left 2px no-repeat;
- }
- .fax {
- background:transparent image-url('icons/fax-32x.png') left 2px no-repeat;
- }
- .skype {
- background:transparent image-url('icons/skype-32x.png') left 2px no-repeat;
- }
- .twitter {
- background:transparent image-url('icons/twitter-32x.png') left 2px no-repeat;
- }
- .voice-message {
- background:transparent image-url('icons/mic-32x.png') left 2px no-repeat;
- }
-
-
-
- .comment {
- @include clearfix;
- border-bottom:1px solid #E3E3E8;
- padding: 11px;
- .display {
- float:left;
- overflow:hidden;
- }
- .info {
- margin-bottom:4px;
- }
- .info,.body {
- padding-left:47px;
- }
- .commenter {
- font-size: 17px;
- font-weight: bold;
- }
- .time {
- color:#929298;
- }
- .info {
- display:block;
- }
- }
-
-
- .display {
- @include border-radius(10px 0 10px 0);
- }
- .description {
- margin:10px 0;
- }
- .widget {
- border-top:1px solid #E3E3E8;
- padding:23px 0;
- width:200px; // Width of the image
- div {
- margin:10px 0;
- padding-left:51px;
- a {
- color:#4B4B4B;
- display:block;
- font-size:size(17px);
- font-weight:bold;
- }
- span {
- color:#E3E3E8;
- font-size:size(12px);
- }
- }
-
- &.adresses {
- strong {
- display:block;
- }
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/pages/_phone_book.scss b/app/assets/stylesheets/app/pages/_phone_book.scss
deleted file mode 100644
index 3670e8e..0000000
--- a/app/assets/stylesheets/app/pages/_phone_book.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-header.tabular-nav { @extend .ext-bradius-t; }
-footer.tabular-nav { @extend .ext-bradius-b; }
-
-.tabular-nav {
- @include clearfix;
- line-height: 41px;
- padding: 0 14px;
- @include gradient(#69ABFB, #75AAEC);
- .pagination {
- float:right;
- }
- nav {
- float:left;
- margin-top: 1px;
- @include size(395px, auto);
- ol {
- @include inline-list;
- a {
- font-weight:bold;
- color:#fff;
- font-size: 14px;
- }
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/shared/_contents.scss b/app/assets/stylesheets/app/shared/_contents.scss
deleted file mode 100644
index 8f88802..0000000
--- a/app/assets/stylesheets/app/shared/_contents.scss
+++ /dev/null
@@ -1,374 +0,0 @@
-// Contents
-// ----------------------------------------´
-
-// Wrap Everything
-#container {
- margin:0 auto;
- width:$site-total-width;
-}
-
-// Global Layout.
-#content {
- @extend .ext-bradius;
- @include gradient(#fff, #FAF9FA);
- border:1px solid #C0C0CA;
- .light {
- @extend .ext-bradius;
- border:1px solid #ECECEF;
- padding:20px;
- }
-}
-
-
-// Content Header Object
-// ----------------------------------------
-
-.breadcrumbs {
- color:$border-dark-color;
- font-size:size(12px);
- margin-bottom: 5px;
- a {
- @include link-colors(#8A8A91, $link-hover-color, #8A8A91, #8A8A91);
- }
-}
-
-header.main {
- border-bottom:1px solid $border-dark-color;
- margin-bottom:20px;
- h1,h2 {
- color:#49494D;
- margin-top:0px;
- }
-}
-
-
-// Flash Notice Object
-// ----------------------------------------
-.flash {
- @extend .ext-bradius;
- @include box-shadow(0px 1px 2px darken(#F0F0F3, 20%));
- font-weight:bold;
- margin-bottom:$vertical-margin;
- position:relative;
- .sign {
- $sign-height: 26px;
- @include pos-y-center($sign-height);
- font-family:Georgia;
- font-size:23px;
- height:$sign-height;
- }
- .light {
- @extend .ext-texture;
- background-position:left bottom;
- padding:15px 21px;
- }
- .message {
- line-height:18px;
- padding-left:26px;
- }
-
- &.notice, &.flash {
- @include text-shadow(1px 1px 1px #EDF3FA);
- background:#CCE4FF;
- color:#37547B;
- }
-
- &.warning, &.alert {
- $border-bottom: #EE9C00;
- $border-light:#EDCC37;
- @include text-shadow(1px 1px 1px #FEF6D7);
- background:#FFE070;
- border:{
- bottom:1px solid $border-bottom;
- top:1px solid lighten(saturate($border-light, 5%), 9%);
- };
- color:#7A2300;
- }
-}
-
-
-// Scaffolding Tables
-// ----------------------------------------
-table {
- th {
- color: #6A747B;
- font-size: 14px;
- font-weight: bold;
- padding: 10px 8px;
- }
- .odd {
- background:#F4F6FB;
- border-bottom:1px solid #EDEFF8;
- }
- td {
- padding:8px;
- }
-}
-
-
-// Pagination Object
-// ----------------------------------------
-.pagination { @include pagination(); }
-
-
-// Entries Object.
-// ----------------------------------------
-header.entries-nav { @extend .ext-bradius-inner-t; }
-footer.entries-nav { @extend .ext-bradius-inner-b; }
-
-.entries-nav {
- @include box-shadow(
- inset 0px 1px 0px #aad2ff, // Light Top
- 0 -1px 0px #A3C9E7, // Shadow Top
- inset 0 -1px 2px #518CBC // Shadow Bottom
- );
- @include clearfix;
- @include gradient(#69ABFB, #75AAEC);
- line-height: 41px;
- padding: 0 14px;
- nav {
- color:#5490C3;
- float:left;
- margin-top: 1px;
- width:540px;
- }
- // ABC
- ol {
- @include inline-list;
- a {
- @include link-colors(#fff, #FFFFC2);
- @include text-shadow(0 2px 0px #5D96CC);
- font-size: 14px;
- font-weight:bold;
- padding:0 3px;
- }
- }
- .pagination {
- float:right;
- }
-}
-
-
-// Phone Book Entry
-// ----------------------------------------
-
-// Title Extension
-.ext-pbe-big { display:block; font-size:size(18px); font-weight:bold; }
-
-.phone-book-entries {
- table { margin:0;}
-}
-// Listing Version
-tr.phone-book-entry {
- @include clearfix;
- color:#7F7F7F;
- td {
- vertical-align:middle;
- }
- &.odd {
- background:#F4F6FB;
- border-bottom:1px solid #EDEFF8;
- }
- img {
- opacity:0.8;
- }
- // All Link colors
- a {
- @include link-colors(#577DA2, $link-color);
- }
- .name {
- @extend .ext-pbe-big;
- }
- .company {
- font-size:size(16px);
- }
- .user {
- @include size(34%);
- }
- .phone {
- @extend .ext-pbe-big;
- }
- .contact {
- @include size(28%);
- }
- .extra {
- @include size(38%);
- }
-}
-
-// Call History Entry
-// ----------------------------------------
-
-.call-history-entries {
- table { margin:0;}
-}
-
-// Listing Version
-tr.call-history-entry {
- @include clearfix;
- color:#7F7F7F;
- td {
- vertical-align:middle;
- }
- &.odd {
- background:#F4F6FB;
- border-bottom:1px solid #EDEFF8;
- }
- img {
- opacity:0.8;
- }
- // All Link colors
- a {
- @include link-colors(#577DA2, $link-color);
- }
- .select_box {
- @include size(2%);
- }
- .thumbnail {
- @include size(5%);
- }
- .time {
- @include size(15%);
- }
- .user {
- @include size(45%);
- }
- .status {
- @include size(15%);
- }
- .actions {
- @include size(5%);
- }
- .name {
- @extend .ext-pbe-big;
- }
- .phone {
- @extend .ext-pbe-big;
- }
- .call-forwarded {
- background:transparent image-url('icons/gs_forward_16x.png') no-repeat;
- padding-left: 20px;
- }
- .call-placed {
- background:transparent image-url('icons/gs_placed_16x.png') no-repeat;
- padding-left: 20px;
- }
- .call-received {
- background:transparent image-url('icons/gs_received_16x.png') no-repeat;
- padding-left: 20px;
- }
- .call-missed {
- background:transparent image-url('icons/gs_missed_16x.png') no-repeat;
- padding-left: 20px;
- }
- .voicemail {
- background:transparent image-url('icons/gs_envelope_16x.png') no-repeat;
- padding-left: 20px;
- }
- .duration {
- @extend .ext-pbe-big;
- }
-}
-
-// Voicemail Messages Entry
-// ----------------------------------------
-
-.voicemail-messages-entries {
- table { margin:0;}
-}
-
-// Listing Version
-tr.voicemail-messages-entry {
- @include clearfix;
- color:#7F7F7F;
- td {
- vertical-align:middle;
- }
- &.odd {
- background:#F4F6FB;
- border-bottom:1px solid #EDEFF8;
- }
- img {
- opacity:0.8;
- }
- // All Link colors
- a {
- @include link-colors(#577DA2, $link-color);
- }
- .select_box {
- @include size(2%);
- }
- .time {
- @include size(15%);
- }
- .folder {
- @include size(10%);
- }
- .user {
- @include size(40%);
- }
- .status {
- @include size(5%);
- }
- .actions {
- @include size(5%);
- }
- .name {
- @extend .ext-pbe-big;
- }
- .phone {
- @extend .ext-pbe-big;
- }
- .voicemail-received {
- background:transparent image-url('icons/gs_received_16x.png') no-repeat;
- padding-left: 20px;
- }
- .voicemail-read {
- background:transparent image-url('icons/gs_envelope_16x.png') no-repeat;
- padding-left: 20px;
- }
- .duration {
- @extend .ext-pbe-big;
- }
-}
-
-
-// users#show
-// ----------------------------------------
-#user-show {
- @include clearfix;
- .display {
- float:left;
- }
- aside {
- float:left;
- padding-top:5px;
- width: 250px;
- p {
- margin-left:70+26px;
- }
- }
- section {
- float:right;
- width:650px;
- h2:first-child {
- margin-top:0;
- }
- }
-}
-
-
-// Simple Form Error Messgaes
-// ----------------------------------------´
-p.error_notification {
- @include gradient(mix(#EB6565, #994F5D, 60%), #994F5D);
- border: 1px solid #7B404A;
- border-radius: 4px;
- box-shadow: inset 1px 1px 0px darken(#f3a0a0, 10%),inset -1px -1px 0px darken(#eb6565, 3%);
- color:#FFF;
- font-weight: bold;
- margin: 0 0 0 158px;
- padding: 10px 15px;
- text-shadow: 2px 2px 1px #82434E;
- width: 282px;
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/shared/_footers.scss b/app/assets/stylesheets/app/shared/_footers.scss
deleted file mode 100644
index be0f54f..0000000
--- a/app/assets/stylesheets/app/shared/_footers.scss
+++ /dev/null
@@ -1,90 +0,0 @@
-// Footers
-// ----------------------------------------
-
-//@include sticky-footer(54px, "#container", "#footer-spacing", "footer");
-
-footer#main {
- @include clearfix;
- position:relative;
- margin:$vertical-margin 0;
- @include gradient(#fff, #FAF9FA);
- border:1px solid #C0C0CA;
- @extend .ext-bradius;
- .light {
- padding:10px 20px;
- border:1px solid #ECECEF;
- @extend .ext-bradius;
- }
-
- ul {
- @include clearfix;
- list-style:none;
- float:left;
- margin:0;
- li {
- float:left;
- margin-bottom: 0px;
- }
- a {
- @include debug;
- line-height:43px;
- padding: 10px 20px;
- border:{
- left:1px solid $border-dark-color;
- };
- }
- li:first-child a{
- border-left:none;
- }
-// @include horizontal-navigation(
-// /*$height : */ 32px,
-// /*$color : */ red,
-// /*$hover-color : */ red,
-// /*$active-color : */ red,
-// /*$text-shadow : */ #530008,
-// /*$bg : */ none,
-// /*$bg-hover : */ none,
-// /*$bg-active : */ none,
-// /*$box-shadow : */ none,
-// /*$box-shadow-hover : */ none,
-// /*$box-shadow-active : */ none,
-// /*$border-light : */ #E3E3E8,
-// /*$border-shadow : */ lighten(#E3E3E8,5%),
-// /*$padding : */ 0 10px,
-// /*$margin : */ none,
-// /*\border-radius : */ none,
-// /*$font-weight : */ none,
-// /*$font-size : */ 14px,
-// /*$tab-space : */ none
-// );
- }
-
-}
-
-.amooma-logo {
- background:#FAF9FA;
- @include debug;
- float:right;
- padding:7px 7px 7px 16px;
- @include border-radius(0 $global-border-radius $global-border-radius 0);
- border-left:1px solid $border-dark-color;
- @include box-shadow(-1px -1px 1px #FFFFFF);
- a {
- @include image-replace('amooma-logo.png');
- float:right;
- opacity:0.6;
- margin: 5px 5px 0 0;
- &:hover {
- opacity:1;
- }
- }
- span {
- @include debug;
- font-size:11px;
- color:#74748B;
- float:left;
- line-height:30px;
- margin-right:10px;
- }
-
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/shared/_handheld.scss b/app/assets/stylesheets/app/shared/_handheld.scss
deleted file mode 100644
index 1efc5e9..0000000
--- a/app/assets/stylesheets/app/shared/_handheld.scss
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// Media queries for responsive design.
-//
-// These follow after primary styles so they will successfully override.
-//
-
-@media all and (orientation:portrait) {
- // Style adjustments for portrait mode goes here
-
-}
-
-@media all and (orientation:landscape) {
- // Style adjustments for landscape mode goes here
-
-}
-
-// Grade-A Mobile Browsers (Opera Mobile, Mobile Safari, Android Chrome)
-// consider this: www.cloudfour.com/css-media-query-for-mobile-is-fools-gold/
-@media screen and (max-device-width: 480px) {
-
-
- // Uncomment if you don't want iOS and WinMobile to mobile-optimize the text for you: j.mp/textsizeadjust
- // html { -webkit-text-size-adjust:none; -ms-text-size-adjust:none; }
-}
-
diff --git a/app/assets/stylesheets/app/shared/_headers.scss b/app/assets/stylesheets/app/shared/_headers.scss
deleted file mode 100644
index 6f8f0fe..0000000
--- a/app/assets/stylesheets/app/shared/_headers.scss
+++ /dev/null
@@ -1,145 +0,0 @@
-// Headers
-// ----------------------------------------
-
-// -- File Variables ----------------------
-
-$border-light:#74B8EA;
-$background: #F0F0F3;
-$user-context-width:227px;
-
-
-// ----------------------------------------
-
-.ext-texture {
- background:transparent image-url('gradients/white-texture-x63.png') left top repeat-x;
-}
-
-.ext-header {
- max-width:$site-total-width - 2px; // Minus the borders
- height:63px;
- @extend .ext-bradius;
-}
-
-
-// Header Object
-// ----------------------------------------
-
-header#main {
- @extend .ext-header;
- background:$background image-url('gradients/light-to-dark-blue-x63.png') left top repeat-x;
- margin:$vertical-margin 0;
- border:1px solid $border-light;
- border-bottom:1px solid #518CBC;
- border-top:1px solid lighten(saturate($border-light, 5%), 9%);
- @include box-shadow(0px 1px 2px darken(#F0F0F3, 20%));
- position:relative;
- overflow:hidden;
- .light {
- @extend .ext-header;
- @extend .ext-texture;
- height:62px;
- border-bottom:1px solid $border-light;
-
- // Used as a spacer for the width
- padding:0 $user-context-width 0 0;
- }
-
- // Resizable Navigation Items.
- span {
- @include debug;
- float:left;
- margin-left:15px;
- font-size:size(17px);
- line-height:62px;
- display:inline;
- float:left;
- margin-right:7px;
- }
-
- .message {
- margin-left:206px;
- }
-
- a {
- @include text-shadow(1px 1px 0px darken(#518CBC, 12%));
- color:#fff;
- &:active, &:hover {
- color:#FFFF70;
- text-decoration:none;
- }
- }
-}
-
-// User Context Object
-// ----------------------------------------
-
-.user-context {
- @include pos(0 10px);
- @include size(200px);
- padding-left:12px;
- text-align:center;
- font-size:size(17px);
- line-height:62px;
- color:#DDDDDD;
- border-left:1px solid $border-light;
- @include box-shadow(-1px -1px 0px #3A91DE);
- // Logged out version of this little guy.
- .display {
- @extend .ext-bradius-inner;
- @include box-shadow(0 -1px 0px #518CBC, 0 1px 0 #74B8EA);
- vertical-align: middle;
- margin: -2px 7px 0 0;
- }
- .logged-out {
- @include box-shadow(none);
- }
- .user {
- width: 170px;
- display: block;
- text-align:left;
- }
- .logout {
- display: block;
- position: absolute;
- top: 0;
- right: 0;
- }
-}
-
-
-// Logo Object
-// ----------------------------------------
-
-.gemeinschaft-logo {
- @include logo('logo.png');
- @include pos(2px 0 0 10px);
- @include debug;
-}
-
-
-// Search Box Object
-// ----------------------------------------
-
-.search-box {
- @extend .ext-bradius-inner;
- float: left;
- margin-left: 200px;
- margin-top: 18px;
- border-bottom: 1px solid #74B7EB;
- position: relative;
- input.text {
- z-index: 0;
- @extend .ext-bradius-inner;
- background: #fff image-url('gradients/white-gray-x29-reverse.png') left top repeat-x;
- line-height: 25px;
- height: 25px;
- border: 1px solid #3472B2;
- @include size(160px, 25px, 0 23px 0 12px);
- }
- input[type="submit"] {
- @include pos(5px 6px 0 0);
- @include image-replace('icons/search-13x16.png');
- border:0;
- }
-}
-
diff --git a/app/assets/stylesheets/app/shared/_ie.scss b/app/assets/stylesheets/app/shared/_ie.scss
deleted file mode 100644
index afbe7e4..0000000
--- a/app/assets/stylesheets/app/shared/_ie.scss
+++ /dev/null
@@ -1,7 +0,0 @@
-// Internet Explorer Hate File.
-// ----------------------------------------
-// Here you'll find all css which it's focused at a specific browser.
-@if in-compatibility-mode() {
- .ie7 {}
- .ie8 {}
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/shared/_media.scss b/app/assets/stylesheets/app/shared/_media.scss
deleted file mode 100644
index c528a1f..0000000
--- a/app/assets/stylesheets/app/shared/_media.scss
+++ /dev/null
@@ -1,16 +0,0 @@
-// Survival ✚ Kit
-// Normalize.css
-
-//PLACEHOLDER Media Queries for Responsive Design.
-//These override the primary ('mobile first') styles
-//Modify as content requires.
-
-@media only screen and (min-width: 480px) {
- /* Style adjustments for viewports 480px and over go here */
-
-}
-
-@media only screen and (min-width: 768px) {
- /* Style adjustments for viewports 768px and over go here */
-
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/app/shared/_print.scss b/app/assets/stylesheets/app/shared/_print.scss
deleted file mode 100644
index c8594e4..0000000
--- a/app/assets/stylesheets/app/shared/_print.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-// Survival ✚ Kit
-// Normalize.css
-
-@media print {
- * { background: transparent !important; color: black !important; text-shadow: none !important; filter:none !important; -ms-filter: none !important; } /* Black prints faster: h5bp.com/s */
- a, a:visited { text-decoration: underline; }
- a[href]:after { content: " (" attr(href) ")"; }
- abbr[title]:after { content: " (" attr(title) ")"; }
- .ir a:after, a[href^="javascript:"]:after, a[href^="#"]:after { content: ""; } /* Don't show links for images, or javascript/internal links */
- pre, blockquote { border: 1px solid #999; page-break-inside: avoid; }
- thead { display: table-header-group; } /* h5bp.com/t */
- tr, img { page-break-inside: avoid; }
- img { max-width: 100% !important; }
- @page { margin: 0.5cm; }
- p, h2, h3 { orphans: 3; widows: 3; }
- h2, h3 { page-break-after: avoid; }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/application.css b/app/assets/stylesheets/application.css
new file mode 100644
index 0000000..9093f8e
--- /dev/null
+++ b/app/assets/stylesheets/application.css
@@ -0,0 +1,15 @@
+/*
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
+ * listed below.
+ *
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
+ *
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
+ * compiled file, but it's generally better to create a new file per style scope.
+ *
+ *= require_self
+ *= require bootstrap/bootstrap
+ *= require bootstrap/bootstrap-responsive
+ *= require gemeinschaft-generic
+ */
diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/stylesheets/application.css.scss
deleted file mode 100644
index 32e54f4..0000000
--- a/app/assets/stylesheets/application.css.scss
+++ /dev/null
@@ -1,117 +0,0 @@
-// Survival ✚ Kit [ Bootstrapper File ]
-
-// Dependencies
-// ----------------------------------------
-@import "vendor/survival-kit/secure";
-@import "compass";
-@import "vendor/boilerplate-1.0/reset";
-@import "vendor/survival-kit/loader";
-@import "vendor/fancy-buttons/fancy-buttons";
-
-
-// Project Variables
-// ----------------------------------------
-// Use @include debug; to show a color overlay on the element when this is set to true.
-$debug : false;
-// Typography
-$base-font-family : "Helvetica Neue", Arial, Helvetica, sans-serif;
-$base-font-size : 13px;
-$base-line-height : 1.231;
-$font-color : #222;
-$link-color : #00e;
-$link-hover-color : #06e;
-$link-visited-color : #551a8b;
-// ETC
-$hr-color : #ccc;
-// Selection
-$selected-font-color : #fff;
-$selected-background-color : #0084AC;
-// Lists
-$list-margin : 1em 0;
-$list-padding : 0 0 0 2em;
-// Container Width
-$container-width : 1000px;
-// Use @if in-compatibility-mode() to add conditional CSS (useful for mixins).
-$compatibility-mode : true, ie7 ie8 ie9 ff2 chrome9;
-
-// -- Project Variables Overrides ---------
-
-$site-total-width : 1000px;
-$vertical-margin : 15px;
-$global-border-radius : 8px;
-$global-inner-border-radius : 6px;
-
-
-// -- Colors ------------------------------
-$link-color:#388DDA;
-$border-dark-color: #E3E3E8;
-
-// Hooks
-// ----------------------------------------
-// Mixins that are called from the Library files to add some extra styling.
-
-@mixin sk-html() { }
-
-@mixin sk-body() {
- background:#F0F3F3 image-url('bg-body.png') left top repeat;
-}
-
-// h1, h2, h3, h4, h5, h6
-@mixin sk-header-tags() {
- font-weight:bold;
-}
-
-
-// Global Styling
-// ----------------------------------------
-// Calculate all H# Tags.
-@include htags-sizes($base-font-size + 20);
-@include simple-forms(auto, block-hints no-stars );
-ul {
- ul {
- margin:0;
- }
-}
-
-// Global Classes for extension.
-// ----------------------------------------
-// Here you place classes which are used as extensions across all the project.
-// Prefix them with .ext-
-
-
-// The default fancy button, used across the SK.
-// @TODO: Turn this into a mixin @include sk-button(small/medium/big);
-.sk-button, .button {
- @include fancy-button(#1E81D5);
-}
-a.button { margin:10px 0;}
-
-// Border Radius
-// ----------------------------------------
-.ext-bradius { @include border-radius($global-border-radius); }
-.ext-bradius-inner-t { @include border-radius($global-inner-border-radius $global-inner-border-radius 0 0); }
-.ext-bradius-inner-b { @include border-radius(0 0 $global-inner-border-radius $global-inner-border-radius); }
-.ext-bradius-inner { @include border-radius($global-inner-border-radius); }
-
-
-// The Partials
-// ----------------------------------------
-// Base styles thanks to html5boilerplate. This one uses the Hooks defined before.
-@import "vendor/boilerplate-1.0/styles";
-
-// -- Shared Partials
- // Headers and related material go here.
- @import "app/shared/headers";
- // Footers and related material go here.
- @import "app/shared/footers";
- // Content and Related Material go here.
- @import "app/shared/contents";
-
-// -- Layouts Partials
- // The most general one goes first
- @import "app/layouts/app";
- @import "app/layouts/phone-book-entry";
- @import "app/layouts/conference";
-
- // Compatibility.. oh jeez.
- @import "app/shared/ie"; \ No newline at end of file
diff --git a/app/assets/stylesheets/bootstrap/bootstrap-responsive.css b/app/assets/stylesheets/bootstrap/bootstrap-responsive.css
new file mode 100644
index 0000000..82fa9ca
--- /dev/null
+++ b/app/assets/stylesheets/bootstrap/bootstrap-responsive.css
@@ -0,0 +1,1088 @@
+/*!
+ * Bootstrap Responsive v2.2.1
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+.clearfix {
+ *zoom: 1;
+}
+
+.clearfix:before,
+.clearfix:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.clearfix:after {
+ clear: both;
+}
+
+.hide-text {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.input-block-level {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.hidden {
+ display: none;
+ visibility: hidden;
+}
+
+.visible-phone {
+ display: none !important;
+}
+
+.visible-tablet {
+ display: none !important;
+}
+
+.hidden-desktop {
+ display: none !important;
+}
+
+.visible-desktop {
+ display: inherit !important;
+}
+
+@media (min-width: 768px) and (max-width: 979px) {
+ .hidden-desktop {
+ display: inherit !important;
+ }
+ .visible-desktop {
+ display: none !important ;
+ }
+ .visible-tablet {
+ display: inherit !important;
+ }
+ .hidden-tablet {
+ display: none !important;
+ }
+}
+
+@media (max-width: 767px) {
+ .hidden-desktop {
+ display: inherit !important;
+ }
+ .visible-desktop {
+ display: none !important;
+ }
+ .visible-phone {
+ display: inherit !important;
+ }
+ .hidden-phone {
+ display: none !important;
+ }
+}
+
+@media (min-width: 1200px) {
+ .row {
+ margin-left: -30px;
+ *zoom: 1;
+ }
+ .row:before,
+ .row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row:after {
+ clear: both;
+ }
+ [class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 30px;
+ }
+ .container,
+ .navbar-static-top .container,
+ .navbar-fixed-top .container,
+ .navbar-fixed-bottom .container {
+ width: 1170px;
+ }
+ .span12 {
+ width: 1170px;
+ }
+ .span11 {
+ width: 1070px;
+ }
+ .span10 {
+ width: 970px;
+ }
+ .span9 {
+ width: 870px;
+ }
+ .span8 {
+ width: 770px;
+ }
+ .span7 {
+ width: 670px;
+ }
+ .span6 {
+ width: 570px;
+ }
+ .span5 {
+ width: 470px;
+ }
+ .span4 {
+ width: 370px;
+ }
+ .span3 {
+ width: 270px;
+ }
+ .span2 {
+ width: 170px;
+ }
+ .span1 {
+ width: 70px;
+ }
+ .offset12 {
+ margin-left: 1230px;
+ }
+ .offset11 {
+ margin-left: 1130px;
+ }
+ .offset10 {
+ margin-left: 1030px;
+ }
+ .offset9 {
+ margin-left: 930px;
+ }
+ .offset8 {
+ margin-left: 830px;
+ }
+ .offset7 {
+ margin-left: 730px;
+ }
+ .offset6 {
+ margin-left: 630px;
+ }
+ .offset5 {
+ margin-left: 530px;
+ }
+ .offset4 {
+ margin-left: 430px;
+ }
+ .offset3 {
+ margin-left: 330px;
+ }
+ .offset2 {
+ margin-left: 230px;
+ }
+ .offset1 {
+ margin-left: 130px;
+ }
+ .row-fluid {
+ width: 100%;
+ *zoom: 1;
+ }
+ .row-fluid:before,
+ .row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row-fluid:after {
+ clear: both;
+ }
+ .row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.564102564102564%;
+ *margin-left: 2.5109110747408616%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+ }
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.564102564102564%;
+ }
+ .row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+ }
+ .row-fluid .span11 {
+ width: 91.45299145299145%;
+ *width: 91.39979996362975%;
+ }
+ .row-fluid .span10 {
+ width: 82.90598290598291%;
+ *width: 82.8527914166212%;
+ }
+ .row-fluid .span9 {
+ width: 74.35897435897436%;
+ *width: 74.30578286961266%;
+ }
+ .row-fluid .span8 {
+ width: 65.81196581196582%;
+ *width: 65.75877432260411%;
+ }
+ .row-fluid .span7 {
+ width: 57.26495726495726%;
+ *width: 57.21176577559556%;
+ }
+ .row-fluid .span6 {
+ width: 48.717948717948715%;
+ *width: 48.664757228587014%;
+ }
+ .row-fluid .span5 {
+ width: 40.17094017094017%;
+ *width: 40.11774868157847%;
+ }
+ .row-fluid .span4 {
+ width: 31.623931623931625%;
+ *width: 31.570740134569924%;
+ }
+ .row-fluid .span3 {
+ width: 23.076923076923077%;
+ *width: 23.023731587561375%;
+ }
+ .row-fluid .span2 {
+ width: 14.52991452991453%;
+ *width: 14.476723040552828%;
+ }
+ .row-fluid .span1 {
+ width: 5.982905982905983%;
+ *width: 5.929714493544281%;
+ }
+ .row-fluid .offset12 {
+ margin-left: 105.12820512820512%;
+ *margin-left: 105.02182214948171%;
+ }
+ .row-fluid .offset12:first-child {
+ margin-left: 102.56410256410257%;
+ *margin-left: 102.45771958537915%;
+ }
+ .row-fluid .offset11 {
+ margin-left: 96.58119658119658%;
+ *margin-left: 96.47481360247316%;
+ }
+ .row-fluid .offset11:first-child {
+ margin-left: 94.01709401709402%;
+ *margin-left: 93.91071103837061%;
+ }
+ .row-fluid .offset10 {
+ margin-left: 88.03418803418803%;
+ *margin-left: 87.92780505546462%;
+ }
+ .row-fluid .offset10:first-child {
+ margin-left: 85.47008547008548%;
+ *margin-left: 85.36370249136206%;
+ }
+ .row-fluid .offset9 {
+ margin-left: 79.48717948717949%;
+ *margin-left: 79.38079650845607%;
+ }
+ .row-fluid .offset9:first-child {
+ margin-left: 76.92307692307693%;
+ *margin-left: 76.81669394435352%;
+ }
+ .row-fluid .offset8 {
+ margin-left: 70.94017094017094%;
+ *margin-left: 70.83378796144753%;
+ }
+ .row-fluid .offset8:first-child {
+ margin-left: 68.37606837606839%;
+ *margin-left: 68.26968539734497%;
+ }
+ .row-fluid .offset7 {
+ margin-left: 62.393162393162385%;
+ *margin-left: 62.28677941443899%;
+ }
+ .row-fluid .offset7:first-child {
+ margin-left: 59.82905982905982%;
+ *margin-left: 59.72267685033642%;
+ }
+ .row-fluid .offset6 {
+ margin-left: 53.84615384615384%;
+ *margin-left: 53.739770867430444%;
+ }
+ .row-fluid .offset6:first-child {
+ margin-left: 51.28205128205128%;
+ *margin-left: 51.175668303327875%;
+ }
+ .row-fluid .offset5 {
+ margin-left: 45.299145299145295%;
+ *margin-left: 45.1927623204219%;
+ }
+ .row-fluid .offset5:first-child {
+ margin-left: 42.73504273504273%;
+ *margin-left: 42.62865975631933%;
+ }
+ .row-fluid .offset4 {
+ margin-left: 36.75213675213675%;
+ *margin-left: 36.645753773413354%;
+ }
+ .row-fluid .offset4:first-child {
+ margin-left: 34.18803418803419%;
+ *margin-left: 34.081651209310785%;
+ }
+ .row-fluid .offset3 {
+ margin-left: 28.205128205128204%;
+ *margin-left: 28.0987452264048%;
+ }
+ .row-fluid .offset3:first-child {
+ margin-left: 25.641025641025642%;
+ *margin-left: 25.53464266230224%;
+ }
+ .row-fluid .offset2 {
+ margin-left: 19.65811965811966%;
+ *margin-left: 19.551736679396257%;
+ }
+ .row-fluid .offset2:first-child {
+ margin-left: 17.094017094017094%;
+ *margin-left: 16.98763411529369%;
+ }
+ .row-fluid .offset1 {
+ margin-left: 11.11111111111111%;
+ *margin-left: 11.004728132387708%;
+ }
+ .row-fluid .offset1:first-child {
+ margin-left: 8.547008547008547%;
+ *margin-left: 8.440625568285142%;
+ }
+ input,
+ textarea,
+ .uneditable-input {
+ margin-left: 0;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 30px;
+ }
+ input.span12,
+ textarea.span12,
+ .uneditable-input.span12 {
+ width: 1156px;
+ }
+ input.span11,
+ textarea.span11,
+ .uneditable-input.span11 {
+ width: 1056px;
+ }
+ input.span10,
+ textarea.span10,
+ .uneditable-input.span10 {
+ width: 956px;
+ }
+ input.span9,
+ textarea.span9,
+ .uneditable-input.span9 {
+ width: 856px;
+ }
+ input.span8,
+ textarea.span8,
+ .uneditable-input.span8 {
+ width: 756px;
+ }
+ input.span7,
+ textarea.span7,
+ .uneditable-input.span7 {
+ width: 656px;
+ }
+ input.span6,
+ textarea.span6,
+ .uneditable-input.span6 {
+ width: 556px;
+ }
+ input.span5,
+ textarea.span5,
+ .uneditable-input.span5 {
+ width: 456px;
+ }
+ input.span4,
+ textarea.span4,
+ .uneditable-input.span4 {
+ width: 356px;
+ }
+ input.span3,
+ textarea.span3,
+ .uneditable-input.span3 {
+ width: 256px;
+ }
+ input.span2,
+ textarea.span2,
+ .uneditable-input.span2 {
+ width: 156px;
+ }
+ input.span1,
+ textarea.span1,
+ .uneditable-input.span1 {
+ width: 56px;
+ }
+ .thumbnails {
+ margin-left: -30px;
+ }
+ .thumbnails > li {
+ margin-left: 30px;
+ }
+ .row-fluid .thumbnails {
+ margin-left: 0;
+ }
+}
+
+@media (min-width: 768px) and (max-width: 979px) {
+ .row {
+ margin-left: -20px;
+ *zoom: 1;
+ }
+ .row:before,
+ .row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row:after {
+ clear: both;
+ }
+ [class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 20px;
+ }
+ .container,
+ .navbar-static-top .container,
+ .navbar-fixed-top .container,
+ .navbar-fixed-bottom .container {
+ width: 724px;
+ }
+ .span12 {
+ width: 724px;
+ }
+ .span11 {
+ width: 662px;
+ }
+ .span10 {
+ width: 600px;
+ }
+ .span9 {
+ width: 538px;
+ }
+ .span8 {
+ width: 476px;
+ }
+ .span7 {
+ width: 414px;
+ }
+ .span6 {
+ width: 352px;
+ }
+ .span5 {
+ width: 290px;
+ }
+ .span4 {
+ width: 228px;
+ }
+ .span3 {
+ width: 166px;
+ }
+ .span2 {
+ width: 104px;
+ }
+ .span1 {
+ width: 42px;
+ }
+ .offset12 {
+ margin-left: 764px;
+ }
+ .offset11 {
+ margin-left: 702px;
+ }
+ .offset10 {
+ margin-left: 640px;
+ }
+ .offset9 {
+ margin-left: 578px;
+ }
+ .offset8 {
+ margin-left: 516px;
+ }
+ .offset7 {
+ margin-left: 454px;
+ }
+ .offset6 {
+ margin-left: 392px;
+ }
+ .offset5 {
+ margin-left: 330px;
+ }
+ .offset4 {
+ margin-left: 268px;
+ }
+ .offset3 {
+ margin-left: 206px;
+ }
+ .offset2 {
+ margin-left: 144px;
+ }
+ .offset1 {
+ margin-left: 82px;
+ }
+ .row-fluid {
+ width: 100%;
+ *zoom: 1;
+ }
+ .row-fluid:before,
+ .row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+ }
+ .row-fluid:after {
+ clear: both;
+ }
+ .row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.7624309392265194%;
+ *margin-left: 2.709239449864817%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+ }
+ .row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.7624309392265194%;
+ }
+ .row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+ }
+ .row-fluid .span11 {
+ width: 91.43646408839778%;
+ *width: 91.38327259903608%;
+ }
+ .row-fluid .span10 {
+ width: 82.87292817679558%;
+ *width: 82.81973668743387%;
+ }
+ .row-fluid .span9 {
+ width: 74.30939226519337%;
+ *width: 74.25620077583166%;
+ }
+ .row-fluid .span8 {
+ width: 65.74585635359117%;
+ *width: 65.69266486422946%;
+ }
+ .row-fluid .span7 {
+ width: 57.18232044198895%;
+ *width: 57.12912895262725%;
+ }
+ .row-fluid .span6 {
+ width: 48.61878453038674%;
+ *width: 48.56559304102504%;
+ }
+ .row-fluid .span5 {
+ width: 40.05524861878453%;
+ *width: 40.00205712942283%;
+ }
+ .row-fluid .span4 {
+ width: 31.491712707182323%;
+ *width: 31.43852121782062%;
+ }
+ .row-fluid .span3 {
+ width: 22.92817679558011%;
+ *width: 22.87498530621841%;
+ }
+ .row-fluid .span2 {
+ width: 14.3646408839779%;
+ *width: 14.311449394616199%;
+ }
+ .row-fluid .span1 {
+ width: 5.801104972375691%;
+ *width: 5.747913483013988%;
+ }
+ .row-fluid .offset12 {
+ margin-left: 105.52486187845304%;
+ *margin-left: 105.41847889972962%;
+ }
+ .row-fluid .offset12:first-child {
+ margin-left: 102.76243093922652%;
+ *margin-left: 102.6560479605031%;
+ }
+ .row-fluid .offset11 {
+ margin-left: 96.96132596685082%;
+ *margin-left: 96.8549429881274%;
+ }
+ .row-fluid .offset11:first-child {
+ margin-left: 94.1988950276243%;
+ *margin-left: 94.09251204890089%;
+ }
+ .row-fluid .offset10 {
+ margin-left: 88.39779005524862%;
+ *margin-left: 88.2914070765252%;
+ }
+ .row-fluid .offset10:first-child {
+ margin-left: 85.6353591160221%;
+ *margin-left: 85.52897613729868%;
+ }
+ .row-fluid .offset9 {
+ margin-left: 79.8342541436464%;
+ *margin-left: 79.72787116492299%;
+ }
+ .row-fluid .offset9:first-child {
+ margin-left: 77.07182320441989%;
+ *margin-left: 76.96544022569647%;
+ }
+ .row-fluid .offset8 {
+ margin-left: 71.2707182320442%;
+ *margin-left: 71.16433525332079%;
+ }
+ .row-fluid .offset8:first-child {
+ margin-left: 68.50828729281768%;
+ *margin-left: 68.40190431409427%;
+ }
+ .row-fluid .offset7 {
+ margin-left: 62.70718232044199%;
+ *margin-left: 62.600799341718584%;
+ }
+ .row-fluid .offset7:first-child {
+ margin-left: 59.94475138121547%;
+ *margin-left: 59.838368402492065%;
+ }
+ .row-fluid .offset6 {
+ margin-left: 54.14364640883978%;
+ *margin-left: 54.037263430116376%;
+ }
+ .row-fluid .offset6:first-child {
+ margin-left: 51.38121546961326%;
+ *margin-left: 51.27483249088986%;
+ }
+ .row-fluid .offset5 {
+ margin-left: 45.58011049723757%;
+ *margin-left: 45.47372751851417%;
+ }
+ .row-fluid .offset5:first-child {
+ margin-left: 42.81767955801105%;
+ *margin-left: 42.71129657928765%;
+ }
+ .row-fluid .offset4 {
+ margin-left: 37.01657458563536%;
+ *margin-left: 36.91019160691196%;
+ }
+ .row-fluid .offset4:first-child {
+ margin-left: 34.25414364640884%;
+ *margin-left: 34.14776066768544%;
+ }
+ .row-fluid .offset3 {
+ margin-left: 28.45303867403315%;
+ *margin-left: 28.346655695309746%;
+ }
+ .row-fluid .offset3:first-child {
+ margin-left: 25.69060773480663%;
+ *margin-left: 25.584224756083227%;
+ }
+ .row-fluid .offset2 {
+ margin-left: 19.88950276243094%;
+ *margin-left: 19.783119783707537%;
+ }
+ .row-fluid .offset2:first-child {
+ margin-left: 17.12707182320442%;
+ *margin-left: 17.02068884448102%;
+ }
+ .row-fluid .offset1 {
+ margin-left: 11.32596685082873%;
+ *margin-left: 11.219583872105325%;
+ }
+ .row-fluid .offset1:first-child {
+ margin-left: 8.56353591160221%;
+ *margin-left: 8.457152932878806%;
+ }
+ input,
+ textarea,
+ .uneditable-input {
+ margin-left: 0;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 20px;
+ }
+ input.span12,
+ textarea.span12,
+ .uneditable-input.span12 {
+ width: 710px;
+ }
+ input.span11,
+ textarea.span11,
+ .uneditable-input.span11 {
+ width: 648px;
+ }
+ input.span10,
+ textarea.span10,
+ .uneditable-input.span10 {
+ width: 586px;
+ }
+ input.span9,
+ textarea.span9,
+ .uneditable-input.span9 {
+ width: 524px;
+ }
+ input.span8,
+ textarea.span8,
+ .uneditable-input.span8 {
+ width: 462px;
+ }
+ input.span7,
+ textarea.span7,
+ .uneditable-input.span7 {
+ width: 400px;
+ }
+ input.span6,
+ textarea.span6,
+ .uneditable-input.span6 {
+ width: 338px;
+ }
+ input.span5,
+ textarea.span5,
+ .uneditable-input.span5 {
+ width: 276px;
+ }
+ input.span4,
+ textarea.span4,
+ .uneditable-input.span4 {
+ width: 214px;
+ }
+ input.span3,
+ textarea.span3,
+ .uneditable-input.span3 {
+ width: 152px;
+ }
+ input.span2,
+ textarea.span2,
+ .uneditable-input.span2 {
+ width: 90px;
+ }
+ input.span1,
+ textarea.span1,
+ .uneditable-input.span1 {
+ width: 28px;
+ }
+}
+
+@media (max-width: 767px) {
+ body {
+ padding-right: 20px;
+ padding-left: 20px;
+ }
+ .navbar-fixed-top,
+ .navbar-fixed-bottom,
+ .navbar-static-top {
+ margin-right: -20px;
+ margin-left: -20px;
+ }
+ .container-fluid {
+ padding: 0;
+ }
+ .dl-horizontal dt {
+ float: none;
+ width: auto;
+ clear: none;
+ text-align: left;
+ }
+ .dl-horizontal dd {
+ margin-left: 0;
+ }
+ .container {
+ width: auto;
+ }
+ .row-fluid {
+ width: 100%;
+ }
+ .row,
+ .thumbnails {
+ margin-left: 0;
+ }
+ .thumbnails > li {
+ float: none;
+ margin-left: 0;
+ }
+ [class*="span"],
+ .uneditable-input[class*="span"],
+ .row-fluid [class*="span"] {
+ display: block;
+ float: none;
+ width: 100%;
+ margin-left: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .span12,
+ .row-fluid .span12 {
+ width: 100%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .row-fluid [class*="offset"]:first-child {
+ margin-left: 0;
+ }
+ .input-large,
+ .input-xlarge,
+ .input-xxlarge,
+ input[class*="span"],
+ select[class*="span"],
+ textarea[class*="span"],
+ .uneditable-input {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ }
+ .input-prepend input,
+ .input-append input,
+ .input-prepend input[class*="span"],
+ .input-append input[class*="span"] {
+ display: inline-block;
+ width: auto;
+ }
+ .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 0;
+ }
+ .modal {
+ position: fixed;
+ top: 20px;
+ right: 20px;
+ left: 20px;
+ width: auto;
+ margin: 0;
+ }
+ .modal.fade {
+ top: -100px;
+ }
+ .modal.fade.in {
+ top: 20px;
+ }
+}
+
+@media (max-width: 480px) {
+ .nav-collapse {
+ -webkit-transform: translate3d(0, 0, 0);
+ }
+ .page-header h1 small {
+ display: block;
+ line-height: 20px;
+ }
+ input[type="checkbox"],
+ input[type="radio"] {
+ border: 1px solid #ccc;
+ }
+ .form-horizontal .control-label {
+ float: none;
+ width: auto;
+ padding-top: 0;
+ text-align: left;
+ }
+ .form-horizontal .controls {
+ margin-left: 0;
+ }
+ .form-horizontal .control-list {
+ padding-top: 0;
+ }
+ .form-horizontal .form-actions {
+ padding-right: 10px;
+ padding-left: 10px;
+ }
+ .media .pull-left,
+ .media .pull-right {
+ display: block;
+ float: none;
+ margin-bottom: 10px;
+ }
+ .media-object {
+ margin-right: 0;
+ margin-left: 0;
+ }
+ .modal {
+ top: 10px;
+ right: 10px;
+ left: 10px;
+ }
+ .modal-header .close {
+ padding: 10px;
+ margin: -10px;
+ }
+ .carousel-caption {
+ position: static;
+ }
+}
+
+@media (max-width: 979px) {
+ body {
+ padding-top: 0;
+ }
+ .navbar-fixed-top,
+ .navbar-fixed-bottom {
+ position: static;
+ }
+ .navbar-fixed-top {
+ margin-bottom: 20px;
+ }
+ .navbar-fixed-bottom {
+ margin-top: 20px;
+ }
+ .navbar-fixed-top .navbar-inner,
+ .navbar-fixed-bottom .navbar-inner {
+ padding: 5px;
+ }
+ .navbar .container {
+ width: auto;
+ padding: 0;
+ }
+ .navbar .brand {
+ padding-right: 10px;
+ padding-left: 10px;
+ margin: 0 0 0 -5px;
+ }
+ .nav-collapse {
+ clear: both;
+ }
+ .nav-collapse .nav {
+ float: none;
+ margin: 0 0 10px;
+ }
+ .nav-collapse .nav > li {
+ float: none;
+ }
+ .nav-collapse .nav > li > a {
+ margin-bottom: 2px;
+ }
+ .nav-collapse .nav > .divider-vertical {
+ display: none;
+ }
+ .nav-collapse .nav .nav-header {
+ color: #777777;
+ text-shadow: none;
+ }
+ .nav-collapse .nav > li > a,
+ .nav-collapse .dropdown-menu a {
+ padding: 9px 15px;
+ font-weight: bold;
+ color: #777777;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+ }
+ .nav-collapse .btn {
+ padding: 4px 10px 4px;
+ font-weight: normal;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ }
+ .nav-collapse .dropdown-menu li + li a {
+ margin-bottom: 2px;
+ }
+ .nav-collapse .nav > li > a:hover,
+ .nav-collapse .dropdown-menu a:hover {
+ background-color: #f2f2f2;
+ }
+ .navbar-inverse .nav-collapse .nav > li > a,
+ .navbar-inverse .nav-collapse .dropdown-menu a {
+ color: #999999;
+ }
+ .navbar-inverse .nav-collapse .nav > li > a:hover,
+ .navbar-inverse .nav-collapse .dropdown-menu a:hover {
+ background-color: #111111;
+ }
+ .nav-collapse.in .btn-group {
+ padding: 0;
+ margin-top: 5px;
+ }
+ .nav-collapse .dropdown-menu {
+ position: static;
+ top: auto;
+ left: auto;
+ display: none;
+ float: none;
+ max-width: none;
+ padding: 0;
+ margin: 0 15px;
+ background-color: transparent;
+ border: none;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+ }
+ .nav-collapse .open > .dropdown-menu {
+ display: block;
+ }
+ .nav-collapse .dropdown-menu:before,
+ .nav-collapse .dropdown-menu:after {
+ display: none;
+ }
+ .nav-collapse .dropdown-menu .divider {
+ display: none;
+ }
+ .nav-collapse .nav > li > .dropdown-menu:before,
+ .nav-collapse .nav > li > .dropdown-menu:after {
+ display: none;
+ }
+ .nav-collapse .navbar-form,
+ .nav-collapse .navbar-search {
+ float: none;
+ padding: 10px 15px;
+ margin: 10px 0;
+ border-top: 1px solid #f2f2f2;
+ border-bottom: 1px solid #f2f2f2;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.1);
+ }
+ .navbar-inverse .nav-collapse .navbar-form,
+ .navbar-inverse .nav-collapse .navbar-search {
+ border-top-color: #111111;
+ border-bottom-color: #111111;
+ }
+ .navbar .nav-collapse .nav.pull-right {
+ float: none;
+ margin-left: 0;
+ }
+ .nav-collapse,
+ .nav-collapse.collapse {
+ height: 0;
+ overflow: hidden;
+ }
+ .navbar .btn-navbar {
+ display: block;
+ }
+ .navbar-static .navbar-inner {
+ padding-right: 10px;
+ padding-left: 10px;
+ }
+}
+
+@media (min-width: 980px) {
+ .nav-collapse.collapse {
+ height: auto !important;
+ overflow: visible !important;
+ }
+}
diff --git a/app/assets/stylesheets/bootstrap/bootstrap.css.erb b/app/assets/stylesheets/bootstrap/bootstrap.css.erb
new file mode 100644
index 0000000..67c4670
--- /dev/null
+++ b/app/assets/stylesheets/bootstrap/bootstrap.css.erb
@@ -0,0 +1,5893 @@
+/*!
+ * Bootstrap v2.2.1
+ *
+ * Copyright 2012 Twitter, Inc
+ * Licensed under the Apache License v2.0
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Designed and built with all the love in the world @twitter by @mdo and @fat.
+ */
+
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+nav,
+section {
+ display: block;
+}
+
+audio,
+canvas,
+video {
+ display: inline-block;
+ *display: inline;
+ *zoom: 1;
+}
+
+audio:not([controls]) {
+ display: none;
+}
+
+html {
+ font-size: 100%;
+ -webkit-text-size-adjust: 100%;
+ -ms-text-size-adjust: 100%;
+}
+
+a:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+a:hover,
+a:active {
+ outline: 0;
+}
+
+sub,
+sup {
+ position: relative;
+ font-size: 75%;
+ line-height: 0;
+ vertical-align: baseline;
+}
+
+sup {
+ top: -0.5em;
+}
+
+sub {
+ bottom: -0.25em;
+}
+
+img {
+ width: auto\9;
+ height: auto;
+ max-width: 100%;
+ vertical-align: middle;
+ border: 0;
+ -ms-interpolation-mode: bicubic;
+}
+
+#map_canvas img,
+.google-maps img {
+ max-width: none;
+}
+
+button,
+input,
+select,
+textarea {
+ margin: 0;
+ font-size: 100%;
+ vertical-align: middle;
+}
+
+button,
+input {
+ *overflow: visible;
+ line-height: normal;
+}
+
+button::-moz-focus-inner,
+input::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+button,
+html input[type="button"],
+input[type="reset"],
+input[type="submit"] {
+ cursor: pointer;
+ -webkit-appearance: button;
+}
+
+input[type="search"] {
+ -webkit-box-sizing: content-box;
+ -moz-box-sizing: content-box;
+ box-sizing: content-box;
+ -webkit-appearance: textfield;
+}
+
+input[type="search"]::-webkit-search-decoration,
+input[type="search"]::-webkit-search-cancel-button {
+ -webkit-appearance: none;
+}
+
+textarea {
+ overflow: auto;
+ vertical-align: top;
+}
+
+.clearfix {
+ *zoom: 1;
+}
+
+.clearfix:before,
+.clearfix:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.clearfix:after {
+ clear: both;
+}
+
+.hide-text {
+ font: 0/0 a;
+ color: transparent;
+ text-shadow: none;
+ background-color: transparent;
+ border: 0;
+}
+
+.input-block-level {
+ display: block;
+ width: 100%;
+ min-height: 30px;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+body {
+ margin: 0;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 14px;
+ line-height: 20px;
+ color: #333333;
+ background-color: #ffffff;
+}
+
+a {
+ color: #0088cc;
+ text-decoration: none;
+}
+
+a:hover {
+ color: #005580;
+ text-decoration: underline;
+}
+
+.img-rounded {
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.img-polaroid {
+ padding: 4px;
+ background-color: #fff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
+}
+
+.img-circle {
+ -webkit-border-radius: 500px;
+ -moz-border-radius: 500px;
+ border-radius: 500px;
+}
+
+.row {
+ margin-left: -20px;
+ *zoom: 1;
+}
+
+.row:before,
+.row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.row:after {
+ clear: both;
+}
+
+[class*="span"] {
+ float: left;
+ min-height: 1px;
+ margin-left: 20px;
+}
+
+.container,
+.navbar-static-top .container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width: 940px;
+}
+
+.span12 {
+ width: 940px;
+}
+
+.span11 {
+ width: 860px;
+}
+
+.span10 {
+ width: 780px;
+}
+
+.span9 {
+ width: 700px;
+}
+
+.span8 {
+ width: 620px;
+}
+
+.span7 {
+ width: 540px;
+}
+
+.span6 {
+ width: 460px;
+}
+
+.span5 {
+ width: 380px;
+}
+
+.span4 {
+ width: 300px;
+}
+
+.span3 {
+ width: 220px;
+}
+
+.span2 {
+ width: 140px;
+}
+
+.span1 {
+ width: 60px;
+}
+
+.offset12 {
+ margin-left: 980px;
+}
+
+.offset11 {
+ margin-left: 900px;
+}
+
+.offset10 {
+ margin-left: 820px;
+}
+
+.offset9 {
+ margin-left: 740px;
+}
+
+.offset8 {
+ margin-left: 660px;
+}
+
+.offset7 {
+ margin-left: 580px;
+}
+
+.offset6 {
+ margin-left: 500px;
+}
+
+.offset5 {
+ margin-left: 420px;
+}
+
+.offset4 {
+ margin-left: 340px;
+}
+
+.offset3 {
+ margin-left: 260px;
+}
+
+.offset2 {
+ margin-left: 180px;
+}
+
+.offset1 {
+ margin-left: 100px;
+}
+
+.row-fluid {
+ width: 100%;
+ *zoom: 1;
+}
+
+.row-fluid:before,
+.row-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.row-fluid:after {
+ clear: both;
+}
+
+.row-fluid [class*="span"] {
+ display: block;
+ float: left;
+ width: 100%;
+ min-height: 30px;
+ margin-left: 2.127659574468085%;
+ *margin-left: 2.074468085106383%;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.row-fluid [class*="span"]:first-child {
+ margin-left: 0;
+}
+
+.row-fluid .controls-row [class*="span"] + [class*="span"] {
+ margin-left: 2.127659574468085%;
+}
+
+.row-fluid .span12 {
+ width: 100%;
+ *width: 99.94680851063829%;
+}
+
+.row-fluid .span11 {
+ width: 91.48936170212765%;
+ *width: 91.43617021276594%;
+}
+
+.row-fluid .span10 {
+ width: 82.97872340425532%;
+ *width: 82.92553191489361%;
+}
+
+.row-fluid .span9 {
+ width: 74.46808510638297%;
+ *width: 74.41489361702126%;
+}
+
+.row-fluid .span8 {
+ width: 65.95744680851064%;
+ *width: 65.90425531914893%;
+}
+
+.row-fluid .span7 {
+ width: 57.44680851063829%;
+ *width: 57.39361702127659%;
+}
+
+.row-fluid .span6 {
+ width: 48.93617021276595%;
+ *width: 48.88297872340425%;
+}
+
+.row-fluid .span5 {
+ width: 40.42553191489362%;
+ *width: 40.37234042553192%;
+}
+
+.row-fluid .span4 {
+ width: 31.914893617021278%;
+ *width: 31.861702127659576%;
+}
+
+.row-fluid .span3 {
+ width: 23.404255319148934%;
+ *width: 23.351063829787233%;
+}
+
+.row-fluid .span2 {
+ width: 14.893617021276595%;
+ *width: 14.840425531914894%;
+}
+
+.row-fluid .span1 {
+ width: 6.382978723404255%;
+ *width: 6.329787234042553%;
+}
+
+.row-fluid .offset12 {
+ margin-left: 104.25531914893617%;
+ *margin-left: 104.14893617021275%;
+}
+
+.row-fluid .offset12:first-child {
+ margin-left: 102.12765957446808%;
+ *margin-left: 102.02127659574467%;
+}
+
+.row-fluid .offset11 {
+ margin-left: 95.74468085106382%;
+ *margin-left: 95.6382978723404%;
+}
+
+.row-fluid .offset11:first-child {
+ margin-left: 93.61702127659574%;
+ *margin-left: 93.51063829787232%;
+}
+
+.row-fluid .offset10 {
+ margin-left: 87.23404255319149%;
+ *margin-left: 87.12765957446807%;
+}
+
+.row-fluid .offset10:first-child {
+ margin-left: 85.1063829787234%;
+ *margin-left: 84.99999999999999%;
+}
+
+.row-fluid .offset9 {
+ margin-left: 78.72340425531914%;
+ *margin-left: 78.61702127659572%;
+}
+
+.row-fluid .offset9:first-child {
+ margin-left: 76.59574468085106%;
+ *margin-left: 76.48936170212764%;
+}
+
+.row-fluid .offset8 {
+ margin-left: 70.2127659574468%;
+ *margin-left: 70.10638297872339%;
+}
+
+.row-fluid .offset8:first-child {
+ margin-left: 68.08510638297872%;
+ *margin-left: 67.9787234042553%;
+}
+
+.row-fluid .offset7 {
+ margin-left: 61.70212765957446%;
+ *margin-left: 61.59574468085106%;
+}
+
+.row-fluid .offset7:first-child {
+ margin-left: 59.574468085106375%;
+ *margin-left: 59.46808510638297%;
+}
+
+.row-fluid .offset6 {
+ margin-left: 53.191489361702125%;
+ *margin-left: 53.085106382978715%;
+}
+
+.row-fluid .offset6:first-child {
+ margin-left: 51.063829787234035%;
+ *margin-left: 50.95744680851063%;
+}
+
+.row-fluid .offset5 {
+ margin-left: 44.68085106382979%;
+ *margin-left: 44.57446808510638%;
+}
+
+.row-fluid .offset5:first-child {
+ margin-left: 42.5531914893617%;
+ *margin-left: 42.4468085106383%;
+}
+
+.row-fluid .offset4 {
+ margin-left: 36.170212765957444%;
+ *margin-left: 36.06382978723405%;
+}
+
+.row-fluid .offset4:first-child {
+ margin-left: 34.04255319148936%;
+ *margin-left: 33.93617021276596%;
+}
+
+.row-fluid .offset3 {
+ margin-left: 27.659574468085104%;
+ *margin-left: 27.5531914893617%;
+}
+
+.row-fluid .offset3:first-child {
+ margin-left: 25.53191489361702%;
+ *margin-left: 25.425531914893618%;
+}
+
+.row-fluid .offset2 {
+ margin-left: 19.148936170212764%;
+ *margin-left: 19.04255319148936%;
+}
+
+.row-fluid .offset2:first-child {
+ margin-left: 17.02127659574468%;
+ *margin-left: 16.914893617021278%;
+}
+
+.row-fluid .offset1 {
+ margin-left: 10.638297872340425%;
+ *margin-left: 10.53191489361702%;
+}
+
+.row-fluid .offset1:first-child {
+ margin-left: 8.51063829787234%;
+ *margin-left: 8.404255319148938%;
+}
+
+[class*="span"].hide,
+.row-fluid [class*="span"].hide {
+ display: none;
+}
+
+[class*="span"].pull-right,
+.row-fluid [class*="span"].pull-right {
+ float: right;
+}
+
+.container {
+ margin-right: auto;
+ margin-left: auto;
+ *zoom: 1;
+}
+
+.container:before,
+.container:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.container:after {
+ clear: both;
+}
+
+.container-fluid {
+ padding-right: 20px;
+ padding-left: 20px;
+ *zoom: 1;
+}
+
+.container-fluid:before,
+.container-fluid:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.container-fluid:after {
+ clear: both;
+}
+
+p {
+ margin: 0 0 10px;
+}
+
+.lead {
+ margin-bottom: 20px;
+ font-size: 21px;
+ font-weight: 200;
+ line-height: 30px;
+}
+
+small {
+ font-size: 85%;
+}
+
+strong {
+ font-weight: bold;
+}
+
+em {
+ font-style: italic;
+}
+
+cite {
+ font-style: normal;
+}
+
+.muted {
+ color: #999999;
+}
+
+.text-warning {
+ color: #c09853;
+}
+
+a.text-warning:hover {
+ color: #a47e3c;
+}
+
+.text-error {
+ color: #b94a48;
+}
+
+a.text-error:hover {
+ color: #953b39;
+}
+
+.text-info {
+ color: #3a87ad;
+}
+
+a.text-info:hover {
+ color: #2d6987;
+}
+
+.text-success {
+ color: #468847;
+}
+
+a.text-success:hover {
+ color: #356635;
+}
+
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+ margin: 10px 0;
+ font-family: inherit;
+ font-weight: bold;
+ line-height: 20px;
+ color: inherit;
+ text-rendering: optimizelegibility;
+}
+
+h1 small,
+h2 small,
+h3 small,
+h4 small,
+h5 small,
+h6 small {
+ font-weight: normal;
+ line-height: 1;
+ color: #999999;
+}
+
+h1,
+h2,
+h3 {
+ line-height: 40px;
+}
+
+h1 {
+ font-size: 38.5px;
+}
+
+h2 {
+ font-size: 31.5px;
+}
+
+h3 {
+ font-size: 24.5px;
+}
+
+h4 {
+ font-size: 17.5px;
+}
+
+h5 {
+ font-size: 14px;
+}
+
+h6 {
+ font-size: 11.9px;
+}
+
+h1 small {
+ font-size: 24.5px;
+}
+
+h2 small {
+ font-size: 17.5px;
+}
+
+h3 small {
+ font-size: 14px;
+}
+
+h4 small {
+ font-size: 14px;
+}
+
+.page-header {
+ padding-bottom: 9px;
+ margin: 20px 0 30px;
+ border-bottom: 1px solid #eeeeee;
+}
+
+ul,
+ol {
+ padding: 0;
+ margin: 0 0 10px 25px;
+}
+
+ul ul,
+ul ol,
+ol ol,
+ol ul {
+ margin-bottom: 0;
+}
+
+li {
+ line-height: 20px;
+}
+
+ul.unstyled,
+ol.unstyled {
+ margin-left: 0;
+ list-style: none;
+}
+
+dl {
+ margin-bottom: 20px;
+}
+
+dt,
+dd {
+ line-height: 20px;
+}
+
+dt {
+ font-weight: bold;
+}
+
+dd {
+ margin-left: 10px;
+}
+
+.dl-horizontal {
+ *zoom: 1;
+}
+
+.dl-horizontal:before,
+.dl-horizontal:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.dl-horizontal:after {
+ clear: both;
+}
+
+.dl-horizontal dt {
+ float: left;
+ width: 160px;
+ overflow: hidden;
+ clear: left;
+ text-align: right;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+
+.dl-horizontal dd {
+ margin-left: 180px;
+}
+
+hr {
+ margin: 20px 0;
+ border: 0;
+ border-top: 1px solid #eeeeee;
+ border-bottom: 1px solid #ffffff;
+}
+
+abbr[title],
+abbr[data-original-title] {
+ cursor: help;
+ border-bottom: 1px dotted #999999;
+}
+
+abbr.initialism {
+ font-size: 90%;
+ text-transform: uppercase;
+}
+
+blockquote {
+ padding: 0 0 0 15px;
+ margin: 0 0 20px;
+ border-left: 5px solid #eeeeee;
+}
+
+blockquote p {
+ margin-bottom: 0;
+ font-size: 16px;
+ font-weight: 300;
+ line-height: 25px;
+}
+
+blockquote small {
+ display: block;
+ line-height: 20px;
+ color: #999999;
+}
+
+blockquote small:before {
+ content: '\2014 \00A0';
+}
+
+blockquote.pull-right {
+ float: right;
+ padding-right: 15px;
+ padding-left: 0;
+ border-right: 5px solid #eeeeee;
+ border-left: 0;
+}
+
+blockquote.pull-right p,
+blockquote.pull-right small {
+ text-align: right;
+}
+
+blockquote.pull-right small:before {
+ content: '';
+}
+
+blockquote.pull-right small:after {
+ content: '\00A0 \2014';
+}
+
+q:before,
+q:after,
+blockquote:before,
+blockquote:after {
+ content: "";
+}
+
+address {
+ display: block;
+ margin-bottom: 20px;
+ font-style: normal;
+ line-height: 20px;
+}
+
+code,
+pre {
+ padding: 0 3px 2px;
+ font-family: Monaco, Menlo, Consolas, "Courier New", monospace;
+ font-size: 12px;
+ color: #333333;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+code {
+ padding: 2px 4px;
+ color: #d14;
+ background-color: #f7f7f9;
+ border: 1px solid #e1e1e8;
+}
+
+pre {
+ display: block;
+ padding: 9.5px;
+ margin: 0 0 10px;
+ font-size: 13px;
+ line-height: 20px;
+ word-break: break-all;
+ word-wrap: break-word;
+ white-space: pre;
+ white-space: pre-wrap;
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.15);
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+pre.prettyprint {
+ margin-bottom: 20px;
+}
+
+pre code {
+ padding: 0;
+ color: inherit;
+ background-color: transparent;
+ border: 0;
+}
+
+.pre-scrollable {
+ max-height: 340px;
+ overflow-y: scroll;
+}
+
+form {
+ margin: 0 0 20px;
+}
+
+fieldset {
+ padding: 0;
+ margin: 0;
+ border: 0;
+}
+
+legend {
+ display: block;
+ width: 100%;
+ padding: 0;
+ margin-bottom: 20px;
+ font-size: 21px;
+ line-height: 40px;
+ color: #333333;
+ border: 0;
+ border-bottom: 1px solid #e5e5e5;
+}
+
+legend small {
+ font-size: 15px;
+ color: #999999;
+}
+
+label,
+input,
+button,
+select,
+textarea {
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 20px;
+}
+
+input,
+button,
+select,
+textarea {
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+}
+
+label {
+ display: block;
+ margin-bottom: 5px;
+}
+
+select,
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ display: inline-block;
+ height: 20px;
+ padding: 4px 6px;
+ margin-bottom: 10px;
+ font-size: 14px;
+ line-height: 20px;
+ color: #555555;
+ vertical-align: middle;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+input,
+textarea,
+.uneditable-input {
+ width: 206px;
+}
+
+textarea {
+ height: auto;
+}
+
+textarea,
+input[type="text"],
+input[type="password"],
+input[type="datetime"],
+input[type="datetime-local"],
+input[type="date"],
+input[type="month"],
+input[type="time"],
+input[type="week"],
+input[type="number"],
+input[type="email"],
+input[type="url"],
+input[type="search"],
+input[type="tel"],
+input[type="color"],
+.uneditable-input {
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -webkit-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -moz-transition: border linear 0.2s, box-shadow linear 0.2s;
+ -o-transition: border linear 0.2s, box-shadow linear 0.2s;
+ transition: border linear 0.2s, box-shadow linear 0.2s;
+}
+
+textarea:focus,
+input[type="text"]:focus,
+input[type="password"]:focus,
+input[type="datetime"]:focus,
+input[type="datetime-local"]:focus,
+input[type="date"]:focus,
+input[type="month"]:focus,
+input[type="time"]:focus,
+input[type="week"]:focus,
+input[type="number"]:focus,
+input[type="email"]:focus,
+input[type="url"]:focus,
+input[type="search"]:focus,
+input[type="tel"]:focus,
+input[type="color"]:focus,
+.uneditable-input:focus {
+ border-color: rgba(82, 168, 236, 0.8);
+ outline: 0;
+ outline: thin dotted \9;
+ /* IE6-9 */
+
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.6);
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+ margin: 4px 0 0;
+ margin-top: 1px \9;
+ *margin-top: 0;
+ line-height: normal;
+ cursor: pointer;
+}
+
+input[type="file"],
+input[type="image"],
+input[type="submit"],
+input[type="reset"],
+input[type="button"],
+input[type="radio"],
+input[type="checkbox"] {
+ width: auto;
+}
+
+select,
+input[type="file"] {
+ height: 30px;
+ /* In IE7, the height of the select element cannot be changed by height, only font-size */
+
+ *margin-top: 4px;
+ /* For IE7, add top margin to align select with labels */
+
+ line-height: 30px;
+}
+
+select {
+ width: 220px;
+ background-color: #ffffff;
+ border: 1px solid #cccccc;
+}
+
+select[multiple],
+select[size] {
+ height: auto;
+}
+
+select:focus,
+input[type="file"]:focus,
+input[type="radio"]:focus,
+input[type="checkbox"]:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.uneditable-input,
+.uneditable-textarea {
+ color: #999999;
+ cursor: not-allowed;
+ background-color: #fcfcfc;
+ border-color: #cccccc;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.025);
+}
+
+.uneditable-input {
+ overflow: hidden;
+ white-space: nowrap;
+}
+
+.uneditable-textarea {
+ width: auto;
+ height: auto;
+}
+
+input:-moz-placeholder,
+textarea:-moz-placeholder {
+ color: #999999;
+}
+
+input:-ms-input-placeholder,
+textarea:-ms-input-placeholder {
+ color: #999999;
+}
+
+input::-webkit-input-placeholder,
+textarea::-webkit-input-placeholder {
+ color: #999999;
+}
+
+.radio,
+.checkbox {
+ min-height: 20px;
+ padding-left: 20px;
+}
+
+.radio input[type="radio"],
+.checkbox input[type="checkbox"] {
+ float: left;
+ margin-left: -20px;
+}
+
+.controls > .radio:first-child,
+.controls > .checkbox:first-child {
+ padding-top: 5px;
+}
+
+.radio.inline,
+.checkbox.inline {
+ display: inline-block;
+ padding-top: 5px;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+.radio.inline + .radio.inline,
+.checkbox.inline + .checkbox.inline {
+ margin-left: 10px;
+}
+
+.input-mini {
+ width: 60px;
+}
+
+.input-small {
+ width: 90px;
+}
+
+.input-medium {
+ width: 150px;
+}
+
+.input-large {
+ width: 210px;
+}
+
+.input-xlarge {
+ width: 270px;
+}
+
+.input-xxlarge {
+ width: 530px;
+}
+
+input[class*="span"],
+select[class*="span"],
+textarea[class*="span"],
+.uneditable-input[class*="span"],
+.row-fluid input[class*="span"],
+.row-fluid select[class*="span"],
+.row-fluid textarea[class*="span"],
+.row-fluid .uneditable-input[class*="span"] {
+ float: none;
+ margin-left: 0;
+}
+
+.input-append input[class*="span"],
+.input-append .uneditable-input[class*="span"],
+.input-prepend input[class*="span"],
+.input-prepend .uneditable-input[class*="span"],
+.row-fluid input[class*="span"],
+.row-fluid select[class*="span"],
+.row-fluid textarea[class*="span"],
+.row-fluid .uneditable-input[class*="span"],
+.row-fluid .input-prepend [class*="span"],
+.row-fluid .input-append [class*="span"] {
+ display: inline-block;
+}
+
+input,
+textarea,
+.uneditable-input {
+ margin-left: 0;
+}
+
+.controls-row [class*="span"] + [class*="span"] {
+ margin-left: 20px;
+}
+
+input.span12,
+textarea.span12,
+.uneditable-input.span12 {
+ width: 926px;
+}
+
+input.span11,
+textarea.span11,
+.uneditable-input.span11 {
+ width: 846px;
+}
+
+input.span10,
+textarea.span10,
+.uneditable-input.span10 {
+ width: 766px;
+}
+
+input.span9,
+textarea.span9,
+.uneditable-input.span9 {
+ width: 686px;
+}
+
+input.span8,
+textarea.span8,
+.uneditable-input.span8 {
+ width: 606px;
+}
+
+input.span7,
+textarea.span7,
+.uneditable-input.span7 {
+ width: 526px;
+}
+
+input.span6,
+textarea.span6,
+.uneditable-input.span6 {
+ width: 446px;
+}
+
+input.span5,
+textarea.span5,
+.uneditable-input.span5 {
+ width: 366px;
+}
+
+input.span4,
+textarea.span4,
+.uneditable-input.span4 {
+ width: 286px;
+}
+
+input.span3,
+textarea.span3,
+.uneditable-input.span3 {
+ width: 206px;
+}
+
+input.span2,
+textarea.span2,
+.uneditable-input.span2 {
+ width: 126px;
+}
+
+input.span1,
+textarea.span1,
+.uneditable-input.span1 {
+ width: 46px;
+}
+
+.controls-row {
+ *zoom: 1;
+}
+
+.controls-row:before,
+.controls-row:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.controls-row:after {
+ clear: both;
+}
+
+.controls-row [class*="span"],
+.row-fluid .controls-row [class*="span"] {
+ float: left;
+}
+
+.controls-row .checkbox[class*="span"],
+.controls-row .radio[class*="span"] {
+ padding-top: 5px;
+}
+
+input[disabled],
+select[disabled],
+textarea[disabled],
+input[readonly],
+select[readonly],
+textarea[readonly] {
+ cursor: not-allowed;
+ background-color: #eeeeee;
+}
+
+input[type="radio"][disabled],
+input[type="checkbox"][disabled],
+input[type="radio"][readonly],
+input[type="checkbox"][readonly] {
+ background-color: transparent;
+}
+
+.control-group.warning > label,
+.control-group.warning .help-block,
+.control-group.warning .help-inline {
+ color: #c09853;
+}
+
+.control-group.warning .checkbox,
+.control-group.warning .radio,
+.control-group.warning input,
+.control-group.warning select,
+.control-group.warning textarea {
+ color: #c09853;
+}
+
+.control-group.warning input,
+.control-group.warning select,
+.control-group.warning textarea {
+ border-color: #c09853;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.warning input:focus,
+.control-group.warning select:focus,
+.control-group.warning textarea:focus {
+ border-color: #a47e3c;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #dbc59e;
+}
+
+.control-group.warning .input-prepend .add-on,
+.control-group.warning .input-append .add-on {
+ color: #c09853;
+ background-color: #fcf8e3;
+ border-color: #c09853;
+}
+
+.control-group.error > label,
+.control-group.error .help-block,
+.control-group.error .help-inline {
+ color: #b94a48;
+}
+
+.control-group.error .checkbox,
+.control-group.error .radio,
+.control-group.error input,
+.control-group.error select,
+.control-group.error textarea {
+ color: #b94a48;
+}
+
+.control-group.error input,
+.control-group.error select,
+.control-group.error textarea {
+ border-color: #b94a48;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.error input:focus,
+.control-group.error select:focus,
+.control-group.error textarea:focus {
+ border-color: #953b39;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #d59392;
+}
+
+.control-group.error .input-prepend .add-on,
+.control-group.error .input-append .add-on {
+ color: #b94a48;
+ background-color: #f2dede;
+ border-color: #b94a48;
+}
+
+.control-group.success > label,
+.control-group.success .help-block,
+.control-group.success .help-inline {
+ color: #468847;
+}
+
+.control-group.success .checkbox,
+.control-group.success .radio,
+.control-group.success input,
+.control-group.success select,
+.control-group.success textarea {
+ color: #468847;
+}
+
+.control-group.success input,
+.control-group.success select,
+.control-group.success textarea {
+ border-color: #468847;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.success input:focus,
+.control-group.success select:focus,
+.control-group.success textarea:focus {
+ border-color: #356635;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7aba7b;
+}
+
+.control-group.success .input-prepend .add-on,
+.control-group.success .input-append .add-on {
+ color: #468847;
+ background-color: #dff0d8;
+ border-color: #468847;
+}
+
+.control-group.info > label,
+.control-group.info .help-block,
+.control-group.info .help-inline {
+ color: #3a87ad;
+}
+
+.control-group.info .checkbox,
+.control-group.info .radio,
+.control-group.info input,
+.control-group.info select,
+.control-group.info textarea {
+ color: #3a87ad;
+}
+
+.control-group.info input,
+.control-group.info select,
+.control-group.info textarea {
+ border-color: #3a87ad;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075);
+}
+
+.control-group.info input:focus,
+.control-group.info select:focus,
+.control-group.info textarea:focus {
+ border-color: #2d6987;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 6px #7ab5d3;
+}
+
+.control-group.info .input-prepend .add-on,
+.control-group.info .input-append .add-on {
+ color: #3a87ad;
+ background-color: #d9edf7;
+ border-color: #3a87ad;
+}
+
+input:focus:required:invalid,
+textarea:focus:required:invalid,
+select:focus:required:invalid {
+ color: #b94a48;
+ border-color: #ee5f5b;
+}
+
+input:focus:required:invalid:focus,
+textarea:focus:required:invalid:focus,
+select:focus:required:invalid:focus {
+ border-color: #e9322d;
+ -webkit-box-shadow: 0 0 6px #f8b9b7;
+ -moz-box-shadow: 0 0 6px #f8b9b7;
+ box-shadow: 0 0 6px #f8b9b7;
+}
+
+.form-actions {
+ padding: 19px 20px 20px;
+ margin-top: 20px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border-top: 1px solid #e5e5e5;
+ *zoom: 1;
+}
+
+.form-actions:before,
+.form-actions:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.form-actions:after {
+ clear: both;
+}
+
+.help-block,
+.help-inline {
+ color: #595959;
+}
+
+.help-block {
+ display: block;
+ margin-bottom: 10px;
+}
+
+.help-inline {
+ display: inline-block;
+ *display: inline;
+ padding-left: 5px;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.input-append,
+.input-prepend {
+ margin-bottom: 5px;
+ font-size: 0;
+ white-space: nowrap;
+}
+
+.input-append input,
+.input-prepend input,
+.input-append select,
+.input-prepend select,
+.input-append .uneditable-input,
+.input-prepend .uneditable-input,
+.input-append .dropdown-menu,
+.input-prepend .dropdown-menu {
+ font-size: 14px;
+}
+
+.input-append input,
+.input-prepend input,
+.input-append select,
+.input-prepend select,
+.input-append .uneditable-input,
+.input-prepend .uneditable-input {
+ position: relative;
+ margin-bottom: 0;
+ *margin-left: 0;
+ vertical-align: top;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-append input:focus,
+.input-prepend input:focus,
+.input-append select:focus,
+.input-prepend select:focus,
+.input-append .uneditable-input:focus,
+.input-prepend .uneditable-input:focus {
+ z-index: 2;
+}
+
+.input-append .add-on,
+.input-prepend .add-on {
+ display: inline-block;
+ width: auto;
+ height: 20px;
+ min-width: 16px;
+ padding: 4px 5px;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 20px;
+ text-align: center;
+ text-shadow: 0 1px 0 #ffffff;
+ background-color: #eeeeee;
+ border: 1px solid #ccc;
+}
+
+.input-append .add-on,
+.input-prepend .add-on,
+.input-append .btn,
+.input-prepend .btn {
+ vertical-align: top;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.input-append .active,
+.input-prepend .active {
+ background-color: #a9dba9;
+ border-color: #46a546;
+}
+
+.input-prepend .add-on,
+.input-prepend .btn {
+ margin-right: -1px;
+}
+
+.input-prepend .add-on:first-child,
+.input-prepend .btn:first-child {
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-append input,
+.input-append select,
+.input-append .uneditable-input {
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-append input + .btn-group .btn,
+.input-append select + .btn-group .btn,
+.input-append .uneditable-input + .btn-group .btn {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-append .add-on,
+.input-append .btn,
+.input-append .btn-group {
+ margin-left: -1px;
+}
+
+.input-append .add-on:last-child,
+.input-append .btn:last-child {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append input,
+.input-prepend.input-append select,
+.input-prepend.input-append .uneditable-input {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.input-prepend.input-append input + .btn-group .btn,
+.input-prepend.input-append select + .btn-group .btn,
+.input-prepend.input-append .uneditable-input + .btn-group .btn {
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append .add-on:first-child,
+.input-prepend.input-append .btn:first-child {
+ margin-right: -1px;
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.input-prepend.input-append .add-on:last-child,
+.input-prepend.input-append .btn:last-child {
+ margin-left: -1px;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.input-prepend.input-append .btn-group:first-child {
+ margin-left: 0;
+}
+
+input.search-query {
+ padding-right: 14px;
+ padding-right: 4px \9;
+ padding-left: 14px;
+ padding-left: 4px \9;
+ /* IE7-8 doesn't have border-radius, so don't indent the padding */
+
+ margin-bottom: 0;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+/* Allow for input prepend/append in search forms */
+
+.form-search .input-append .search-query,
+.form-search .input-prepend .search-query {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.form-search .input-append .search-query {
+ -webkit-border-radius: 14px 0 0 14px;
+ -moz-border-radius: 14px 0 0 14px;
+ border-radius: 14px 0 0 14px;
+}
+
+.form-search .input-append .btn {
+ -webkit-border-radius: 0 14px 14px 0;
+ -moz-border-radius: 0 14px 14px 0;
+ border-radius: 0 14px 14px 0;
+}
+
+.form-search .input-prepend .search-query {
+ -webkit-border-radius: 0 14px 14px 0;
+ -moz-border-radius: 0 14px 14px 0;
+ border-radius: 0 14px 14px 0;
+}
+
+.form-search .input-prepend .btn {
+ -webkit-border-radius: 14px 0 0 14px;
+ -moz-border-radius: 14px 0 0 14px;
+ border-radius: 14px 0 0 14px;
+}
+
+.form-search input,
+.form-inline input,
+.form-horizontal input,
+.form-search textarea,
+.form-inline textarea,
+.form-horizontal textarea,
+.form-search select,
+.form-inline select,
+.form-horizontal select,
+.form-search .help-inline,
+.form-inline .help-inline,
+.form-horizontal .help-inline,
+.form-search .uneditable-input,
+.form-inline .uneditable-input,
+.form-horizontal .uneditable-input,
+.form-search .input-prepend,
+.form-inline .input-prepend,
+.form-horizontal .input-prepend,
+.form-search .input-append,
+.form-inline .input-append,
+.form-horizontal .input-append {
+ display: inline-block;
+ *display: inline;
+ margin-bottom: 0;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.form-search .hide,
+.form-inline .hide,
+.form-horizontal .hide {
+ display: none;
+}
+
+.form-search label,
+.form-inline label,
+.form-search .btn-group,
+.form-inline .btn-group {
+ display: inline-block;
+}
+
+.form-search .input-append,
+.form-inline .input-append,
+.form-search .input-prepend,
+.form-inline .input-prepend {
+ margin-bottom: 0;
+}
+
+.form-search .radio,
+.form-search .checkbox,
+.form-inline .radio,
+.form-inline .checkbox {
+ padding-left: 0;
+ margin-bottom: 0;
+ vertical-align: middle;
+}
+
+.form-search .radio input[type="radio"],
+.form-search .checkbox input[type="checkbox"],
+.form-inline .radio input[type="radio"],
+.form-inline .checkbox input[type="checkbox"] {
+ float: left;
+ margin-right: 3px;
+ margin-left: 0;
+}
+
+.control-group {
+ margin-bottom: 10px;
+}
+
+legend + .control-group {
+ margin-top: 20px;
+ -webkit-margin-top-collapse: separate;
+}
+
+.form-horizontal .control-group {
+ margin-bottom: 20px;
+ *zoom: 1;
+}
+
+.form-horizontal .control-group:before,
+.form-horizontal .control-group:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.form-horizontal .control-group:after {
+ clear: both;
+}
+
+.form-horizontal .control-label {
+ float: left;
+ width: 160px;
+ padding-top: 5px;
+ text-align: right;
+}
+
+.form-horizontal .controls {
+ *display: inline-block;
+ *padding-left: 20px;
+ margin-left: 180px;
+ *margin-left: 0;
+}
+
+.form-horizontal .controls:first-child {
+ *padding-left: 180px;
+}
+
+.form-horizontal .help-block {
+ margin-bottom: 0;
+}
+
+.form-horizontal input + .help-block,
+.form-horizontal select + .help-block,
+.form-horizontal textarea + .help-block {
+ margin-top: 10px;
+}
+
+.form-horizontal .form-actions {
+ padding-left: 180px;
+}
+
+table {
+ max-width: 100%;
+ background-color: transparent;
+ border-collapse: collapse;
+ border-spacing: 0;
+}
+
+.table {
+ width: 100%;
+ margin-bottom: 20px;
+}
+
+.table th,
+.table td {
+ padding: 8px;
+ line-height: 20px;
+ text-align: left;
+ vertical-align: top;
+ border-top: 1px solid #dddddd;
+}
+
+.table th {
+ font-weight: bold;
+}
+
+.table thead th {
+ vertical-align: bottom;
+}
+
+.table caption + thead tr:first-child th,
+.table caption + thead tr:first-child td,
+.table colgroup + thead tr:first-child th,
+.table colgroup + thead tr:first-child td,
+.table thead:first-child tr:first-child th,
+.table thead:first-child tr:first-child td {
+ border-top: 0;
+}
+
+.table tbody + tbody {
+ border-top: 2px solid #dddddd;
+}
+
+.table-condensed th,
+.table-condensed td {
+ padding: 4px 5px;
+}
+
+.table-bordered {
+ border: 1px solid #dddddd;
+ border-collapse: separate;
+ *border-collapse: collapse;
+ border-left: 0;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.table-bordered th,
+.table-bordered td {
+ border-left: 1px solid #dddddd;
+}
+
+.table-bordered caption + thead tr:first-child th,
+.table-bordered caption + tbody tr:first-child th,
+.table-bordered caption + tbody tr:first-child td,
+.table-bordered colgroup + thead tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child th,
+.table-bordered colgroup + tbody tr:first-child td,
+.table-bordered thead:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child th,
+.table-bordered tbody:first-child tr:first-child td {
+ border-top: 0;
+}
+
+.table-bordered thead:first-child tr:first-child th:first-child,
+.table-bordered tbody:first-child tr:first-child td:first-child {
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.table-bordered thead:first-child tr:first-child th:last-child,
+.table-bordered tbody:first-child tr:first-child td:last-child {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+}
+
+.table-bordered thead:last-child tr:last-child th:first-child,
+.table-bordered tbody:last-child tr:last-child td:first-child,
+.table-bordered tfoot:last-child tr:last-child td:first-child {
+ -webkit-border-radius: 0 0 0 4px;
+ -moz-border-radius: 0 0 0 4px;
+ border-radius: 0 0 0 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+}
+
+.table-bordered thead:last-child tr:last-child th:last-child,
+.table-bordered tbody:last-child tr:last-child td:last-child,
+.table-bordered tfoot:last-child tr:last-child td:last-child {
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.table-bordered caption + thead tr:first-child th:first-child,
+.table-bordered caption + tbody tr:first-child td:first-child,
+.table-bordered colgroup + thead tr:first-child th:first-child,
+.table-bordered colgroup + tbody tr:first-child td:first-child {
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.table-bordered caption + thead tr:first-child th:last-child,
+.table-bordered caption + tbody tr:first-child td:last-child,
+.table-bordered colgroup + thead tr:first-child th:last-child,
+.table-bordered colgroup + tbody tr:first-child td:last-child {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+}
+
+.table-striped tbody tr:nth-child(odd) td,
+.table-striped tbody tr:nth-child(odd) th {
+ background-color: #f9f9f9;
+}
+
+.table-hover tbody tr:hover td,
+.table-hover tbody tr:hover th {
+ background-color: #f5f5f5;
+}
+
+table td[class*="span"],
+table th[class*="span"],
+.row-fluid table td[class*="span"],
+.row-fluid table th[class*="span"] {
+ display: table-cell;
+ float: none;
+ margin-left: 0;
+}
+
+.table td.span1,
+.table th.span1 {
+ float: none;
+ width: 44px;
+ margin-left: 0;
+}
+
+.table td.span2,
+.table th.span2 {
+ float: none;
+ width: 124px;
+ margin-left: 0;
+}
+
+.table td.span3,
+.table th.span3 {
+ float: none;
+ width: 204px;
+ margin-left: 0;
+}
+
+.table td.span4,
+.table th.span4 {
+ float: none;
+ width: 284px;
+ margin-left: 0;
+}
+
+.table td.span5,
+.table th.span5 {
+ float: none;
+ width: 364px;
+ margin-left: 0;
+}
+
+.table td.span6,
+.table th.span6 {
+ float: none;
+ width: 444px;
+ margin-left: 0;
+}
+
+.table td.span7,
+.table th.span7 {
+ float: none;
+ width: 524px;
+ margin-left: 0;
+}
+
+.table td.span8,
+.table th.span8 {
+ float: none;
+ width: 604px;
+ margin-left: 0;
+}
+
+.table td.span9,
+.table th.span9 {
+ float: none;
+ width: 684px;
+ margin-left: 0;
+}
+
+.table td.span10,
+.table th.span10 {
+ float: none;
+ width: 764px;
+ margin-left: 0;
+}
+
+.table td.span11,
+.table th.span11 {
+ float: none;
+ width: 844px;
+ margin-left: 0;
+}
+
+.table td.span12,
+.table th.span12 {
+ float: none;
+ width: 924px;
+ margin-left: 0;
+}
+
+.table tbody tr.success td {
+ background-color: #dff0d8;
+}
+
+.table tbody tr.error td {
+ background-color: #f2dede;
+}
+
+.table tbody tr.warning td {
+ background-color: #fcf8e3;
+}
+
+.table tbody tr.info td {
+ background-color: #d9edf7;
+}
+
+.table-hover tbody tr.success:hover td {
+ background-color: #d0e9c6;
+}
+
+.table-hover tbody tr.error:hover td {
+ background-color: #ebcccc;
+}
+
+.table-hover tbody tr.warning:hover td {
+ background-color: #faf2cc;
+}
+
+.table-hover tbody tr.info:hover td {
+ background-color: #c4e3f3;
+}
+
+[class^="icon-"],
+[class*=" icon-"] {
+ display: inline-block;
+ width: 14px;
+ height: 14px;
+ margin-top: 1px;
+ *margin-right: .3em;
+ line-height: 14px;
+ vertical-align: text-top;
+ background-image: url(<%= asset_path '/assets/icons/glyphicons-halflings.png' %>);
+ background-position: 14px 14px;
+ background-repeat: no-repeat;
+}
+
+/* White icons with optional class, or on hover/active states of certain elements */
+
+.icon-white,
+.nav-pills > .active > a > [class^="icon-"],
+.nav-pills > .active > a > [class*=" icon-"],
+.nav-list > .active > a > [class^="icon-"],
+.nav-list > .active > a > [class*=" icon-"],
+.navbar-inverse .nav > .active > a > [class^="icon-"],
+.navbar-inverse .nav > .active > a > [class*=" icon-"],
+.dropdown-menu > li > a:hover > [class^="icon-"],
+.dropdown-menu > li > a:hover > [class*=" icon-"],
+.dropdown-menu > .active > a > [class^="icon-"],
+.dropdown-menu > .active > a > [class*=" icon-"],
+.dropdown-submenu:hover > a > [class^="icon-"],
+.dropdown-submenu:hover > a > [class*=" icon-"] {
+ background-image: url(<%= asset_path '/assets/icons/glyphicons-halflings-white.png' %>);
+}
+
+.icon-glass {
+ background-position: 0 0;
+}
+
+.icon-music {
+ background-position: -24px 0;
+}
+
+.icon-search {
+ background-position: -48px 0;
+}
+
+.icon-envelope {
+ background-position: -72px 0;
+}
+
+.icon-heart {
+ background-position: -96px 0;
+}
+
+.icon-star {
+ background-position: -120px 0;
+}
+
+.icon-star-empty {
+ background-position: -144px 0;
+}
+
+.icon-user {
+ background-position: -168px 0;
+}
+
+.icon-film {
+ background-position: -192px 0;
+}
+
+.icon-th-large {
+ background-position: -216px 0;
+}
+
+.icon-th {
+ background-position: -240px 0;
+}
+
+.icon-th-list {
+ background-position: -264px 0;
+}
+
+.icon-ok {
+ background-position: -288px 0;
+}
+
+.icon-remove {
+ background-position: -312px 0;
+}
+
+.icon-zoom-in {
+ background-position: -336px 0;
+}
+
+.icon-zoom-out {
+ background-position: -360px 0;
+}
+
+.icon-off {
+ background-position: -384px 0;
+}
+
+.icon-signal {
+ background-position: -408px 0;
+}
+
+.icon-cog {
+ background-position: -432px 0;
+}
+
+.icon-trash {
+ background-position: -456px 0;
+}
+
+.icon-home {
+ background-position: 0 -24px;
+}
+
+.icon-file {
+ background-position: -24px -24px;
+}
+
+.icon-time {
+ background-position: -48px -24px;
+}
+
+.icon-road {
+ background-position: -72px -24px;
+}
+
+.icon-download-alt {
+ background-position: -96px -24px;
+}
+
+.icon-download {
+ background-position: -120px -24px;
+}
+
+.icon-upload {
+ background-position: -144px -24px;
+}
+
+.icon-inbox {
+ background-position: -168px -24px;
+}
+
+.icon-play-circle {
+ background-position: -192px -24px;
+}
+
+.icon-repeat {
+ background-position: -216px -24px;
+}
+
+.icon-refresh {
+ background-position: -240px -24px;
+}
+
+.icon-list-alt {
+ background-position: -264px -24px;
+}
+
+.icon-lock {
+ background-position: -287px -24px;
+}
+
+.icon-flag {
+ background-position: -312px -24px;
+}
+
+.icon-headphones {
+ background-position: -336px -24px;
+}
+
+.icon-volume-off {
+ background-position: -360px -24px;
+}
+
+.icon-volume-down {
+ background-position: -384px -24px;
+}
+
+.icon-volume-up {
+ background-position: -408px -24px;
+}
+
+.icon-qrcode {
+ background-position: -432px -24px;
+}
+
+.icon-barcode {
+ background-position: -456px -24px;
+}
+
+.icon-tag {
+ background-position: 0 -48px;
+}
+
+.icon-tags {
+ background-position: -25px -48px;
+}
+
+.icon-book {
+ background-position: -48px -48px;
+}
+
+.icon-bookmark {
+ background-position: -72px -48px;
+}
+
+.icon-print {
+ background-position: -96px -48px;
+}
+
+.icon-camera {
+ background-position: -120px -48px;
+}
+
+.icon-font {
+ background-position: -144px -48px;
+}
+
+.icon-bold {
+ background-position: -167px -48px;
+}
+
+.icon-italic {
+ background-position: -192px -48px;
+}
+
+.icon-text-height {
+ background-position: -216px -48px;
+}
+
+.icon-text-width {
+ background-position: -240px -48px;
+}
+
+.icon-align-left {
+ background-position: -264px -48px;
+}
+
+.icon-align-center {
+ background-position: -288px -48px;
+}
+
+.icon-align-right {
+ background-position: -312px -48px;
+}
+
+.icon-align-justify {
+ background-position: -336px -48px;
+}
+
+.icon-list {
+ background-position: -360px -48px;
+}
+
+.icon-indent-left {
+ background-position: -384px -48px;
+}
+
+.icon-indent-right {
+ background-position: -408px -48px;
+}
+
+.icon-facetime-video {
+ background-position: -432px -48px;
+}
+
+.icon-picture {
+ background-position: -456px -48px;
+}
+
+.icon-pencil {
+ background-position: 0 -72px;
+}
+
+.icon-map-marker {
+ background-position: -24px -72px;
+}
+
+.icon-adjust {
+ background-position: -48px -72px;
+}
+
+.icon-tint {
+ background-position: -72px -72px;
+}
+
+.icon-edit {
+ background-position: -96px -72px;
+}
+
+.icon-share {
+ background-position: -120px -72px;
+}
+
+.icon-check {
+ background-position: -144px -72px;
+}
+
+.icon-move {
+ background-position: -168px -72px;
+}
+
+.icon-step-backward {
+ background-position: -192px -72px;
+}
+
+.icon-fast-backward {
+ background-position: -216px -72px;
+}
+
+.icon-backward {
+ background-position: -240px -72px;
+}
+
+.icon-play {
+ background-position: -264px -72px;
+}
+
+.icon-pause {
+ background-position: -288px -72px;
+}
+
+.icon-stop {
+ background-position: -312px -72px;
+}
+
+.icon-forward {
+ background-position: -336px -72px;
+}
+
+.icon-fast-forward {
+ background-position: -360px -72px;
+}
+
+.icon-step-forward {
+ background-position: -384px -72px;
+}
+
+.icon-eject {
+ background-position: -408px -72px;
+}
+
+.icon-chevron-left {
+ background-position: -432px -72px;
+}
+
+.icon-chevron-right {
+ background-position: -456px -72px;
+}
+
+.icon-plus-sign {
+ background-position: 0 -96px;
+}
+
+.icon-minus-sign {
+ background-position: -24px -96px;
+}
+
+.icon-remove-sign {
+ background-position: -48px -96px;
+}
+
+.icon-ok-sign {
+ background-position: -72px -96px;
+}
+
+.icon-question-sign {
+ background-position: -96px -96px;
+}
+
+.icon-info-sign {
+ background-position: -120px -96px;
+}
+
+.icon-screenshot {
+ background-position: -144px -96px;
+}
+
+.icon-remove-circle {
+ background-position: -168px -96px;
+}
+
+.icon-ok-circle {
+ background-position: -192px -96px;
+}
+
+.icon-ban-circle {
+ background-position: -216px -96px;
+}
+
+.icon-arrow-left {
+ background-position: -240px -96px;
+}
+
+.icon-arrow-right {
+ background-position: -264px -96px;
+}
+
+.icon-arrow-up {
+ background-position: -289px -96px;
+}
+
+.icon-arrow-down {
+ background-position: -312px -96px;
+}
+
+.icon-share-alt {
+ background-position: -336px -96px;
+}
+
+.icon-resize-full {
+ background-position: -360px -96px;
+}
+
+.icon-resize-small {
+ background-position: -384px -96px;
+}
+
+.icon-plus {
+ background-position: -408px -96px;
+}
+
+.icon-minus {
+ background-position: -433px -96px;
+}
+
+.icon-asterisk {
+ background-position: -456px -96px;
+}
+
+.icon-exclamation-sign {
+ background-position: 0 -120px;
+}
+
+.icon-gift {
+ background-position: -24px -120px;
+}
+
+.icon-leaf {
+ background-position: -48px -120px;
+}
+
+.icon-fire {
+ background-position: -72px -120px;
+}
+
+.icon-eye-open {
+ background-position: -96px -120px;
+}
+
+.icon-eye-close {
+ background-position: -120px -120px;
+}
+
+.icon-warning-sign {
+ background-position: -144px -120px;
+}
+
+.icon-plane {
+ background-position: -168px -120px;
+}
+
+.icon-calendar {
+ background-position: -192px -120px;
+}
+
+.icon-random {
+ width: 16px;
+ background-position: -216px -120px;
+}
+
+.icon-comment {
+ background-position: -240px -120px;
+}
+
+.icon-magnet {
+ background-position: -264px -120px;
+}
+
+.icon-chevron-up {
+ background-position: -288px -120px;
+}
+
+.icon-chevron-down {
+ background-position: -313px -119px;
+}
+
+.icon-retweet {
+ background-position: -336px -120px;
+}
+
+.icon-shopping-cart {
+ background-position: -360px -120px;
+}
+
+.icon-folder-close {
+ background-position: -384px -120px;
+}
+
+.icon-folder-open {
+ width: 16px;
+ background-position: -408px -120px;
+}
+
+.icon-resize-vertical {
+ background-position: -432px -119px;
+}
+
+.icon-resize-horizontal {
+ background-position: -456px -118px;
+}
+
+.icon-hdd {
+ background-position: 0 -144px;
+}
+
+.icon-bullhorn {
+ background-position: -24px -144px;
+}
+
+.icon-bell {
+ background-position: -48px -144px;
+}
+
+.icon-certificate {
+ background-position: -72px -144px;
+}
+
+.icon-thumbs-up {
+ background-position: -96px -144px;
+}
+
+.icon-thumbs-down {
+ background-position: -120px -144px;
+}
+
+.icon-hand-right {
+ background-position: -144px -144px;
+}
+
+.icon-hand-left {
+ background-position: -168px -144px;
+}
+
+.icon-hand-up {
+ background-position: -192px -144px;
+}
+
+.icon-hand-down {
+ background-position: -216px -144px;
+}
+
+.icon-circle-arrow-right {
+ background-position: -240px -144px;
+}
+
+.icon-circle-arrow-left {
+ background-position: -264px -144px;
+}
+
+.icon-circle-arrow-up {
+ background-position: -288px -144px;
+}
+
+.icon-circle-arrow-down {
+ background-position: -312px -144px;
+}
+
+.icon-globe {
+ background-position: -336px -144px;
+}
+
+.icon-wrench {
+ background-position: -360px -144px;
+}
+
+.icon-tasks {
+ background-position: -384px -144px;
+}
+
+.icon-filter {
+ background-position: -408px -144px;
+}
+
+.icon-briefcase {
+ background-position: -432px -144px;
+}
+
+.icon-fullscreen {
+ background-position: -456px -144px;
+}
+
+.dropup,
+.dropdown {
+ position: relative;
+}
+
+.dropdown-toggle {
+ *margin-bottom: -3px;
+}
+
+.dropdown-toggle:active,
+.open .dropdown-toggle {
+ outline: 0;
+}
+
+.caret {
+ display: inline-block;
+ width: 0;
+ height: 0;
+ vertical-align: top;
+ border-top: 4px solid #000000;
+ border-right: 4px solid transparent;
+ border-left: 4px solid transparent;
+ content: "";
+}
+
+.dropdown .caret {
+ margin-top: 8px;
+ margin-left: 2px;
+}
+
+.dropdown-menu {
+ position: absolute;
+ top: 100%;
+ left: 0;
+ z-index: 1000;
+ display: none;
+ float: left;
+ min-width: 160px;
+ padding: 5px 0;
+ margin: 2px 0 0;
+ list-style: none;
+ background-color: #ffffff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ *border-right-width: 2px;
+ *border-bottom-width: 2px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+}
+
+.dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.dropdown-menu .divider {
+ *width: 100%;
+ height: 1px;
+ margin: 9px 1px;
+ *margin: -5px 0 5px;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ border-bottom: 1px solid #ffffff;
+}
+
+.dropdown-menu li > a {
+ display: block;
+ padding: 3px 20px;
+ clear: both;
+ font-weight: normal;
+ line-height: 20px;
+ color: #333333;
+ white-space: nowrap;
+}
+
+.dropdown-menu li > a:hover,
+.dropdown-menu li > a:focus,
+.dropdown-submenu:hover > a {
+ color: #ffffff;
+ text-decoration: none;
+ background-color: #0081c2;
+ background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -o-linear-gradient(top, #0088cc, #0077b3);
+ background-image: linear-gradient(to bottom, #0088cc, #0077b3);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
+}
+
+.dropdown-menu .active > a,
+.dropdown-menu .active > a:hover {
+ color: #333333;
+ text-decoration: none;
+ background-color: #0081c2;
+ background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
+ background-image: -o-linear-gradient(top, #0088cc, #0077b3);
+ background-image: linear-gradient(to bottom, #0088cc, #0077b3);
+ background-repeat: repeat-x;
+ outline: 0;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);
+}
+
+.dropdown-menu .disabled > a,
+.dropdown-menu .disabled > a:hover {
+ color: #999999;
+}
+
+.dropdown-menu .disabled > a:hover {
+ text-decoration: none;
+ cursor: default;
+ background-color: transparent;
+ background-image: none;
+}
+
+.open {
+ *z-index: 1000;
+}
+
+.open > .dropdown-menu {
+ display: block;
+}
+
+.pull-right > .dropdown-menu {
+ right: 0;
+ left: auto;
+}
+
+.dropup .caret,
+.navbar-fixed-bottom .dropdown .caret {
+ border-top: 0;
+ border-bottom: 4px solid #000000;
+ content: "";
+}
+
+.dropup .dropdown-menu,
+.navbar-fixed-bottom .dropdown .dropdown-menu {
+ top: auto;
+ bottom: 100%;
+ margin-bottom: 1px;
+}
+
+.dropdown-submenu {
+ position: relative;
+}
+
+.dropdown-submenu > .dropdown-menu {
+ top: 0;
+ left: 100%;
+ margin-top: -6px;
+ margin-left: -1px;
+ -webkit-border-radius: 0 6px 6px 6px;
+ -moz-border-radius: 0 6px 6px 6px;
+ border-radius: 0 6px 6px 6px;
+}
+
+.dropdown-submenu:hover > .dropdown-menu {
+ display: block;
+}
+
+.dropup .dropdown-submenu > .dropdown-menu {
+ top: auto;
+ bottom: 0;
+ margin-top: 0;
+ margin-bottom: -2px;
+ -webkit-border-radius: 5px 5px 5px 0;
+ -moz-border-radius: 5px 5px 5px 0;
+ border-radius: 5px 5px 5px 0;
+}
+
+.dropdown-submenu > a:after {
+ display: block;
+ float: right;
+ width: 0;
+ height: 0;
+ margin-top: 5px;
+ margin-right: -10px;
+ border-color: transparent;
+ border-left-color: #cccccc;
+ border-style: solid;
+ border-width: 5px 0 5px 5px;
+ content: " ";
+}
+
+.dropdown-submenu:hover > a:after {
+ border-left-color: #ffffff;
+}
+
+.dropdown-submenu.pull-left {
+ float: none;
+}
+
+.dropdown-submenu.pull-left > .dropdown-menu {
+ left: -100%;
+ margin-left: 10px;
+ -webkit-border-radius: 6px 0 6px 6px;
+ -moz-border-radius: 6px 0 6px 6px;
+ border-radius: 6px 0 6px 6px;
+}
+
+.dropdown .dropdown-menu .nav-header {
+ padding-right: 20px;
+ padding-left: 20px;
+}
+
+.typeahead {
+ margin-top: 2px;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.well {
+ min-height: 20px;
+ padding: 19px;
+ margin-bottom: 20px;
+ background-color: #f5f5f5;
+ border: 1px solid #e3e3e3;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.05);
+}
+
+.well blockquote {
+ border-color: #ddd;
+ border-color: rgba(0, 0, 0, 0.15);
+}
+
+.well-large {
+ padding: 24px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.well-small {
+ padding: 9px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.fade {
+ opacity: 0;
+ -webkit-transition: opacity 0.15s linear;
+ -moz-transition: opacity 0.15s linear;
+ -o-transition: opacity 0.15s linear;
+ transition: opacity 0.15s linear;
+}
+
+.fade.in {
+ opacity: 1;
+}
+
+.collapse {
+ position: relative;
+ height: 0;
+ overflow: hidden;
+ -webkit-transition: height 0.35s ease;
+ -moz-transition: height 0.35s ease;
+ -o-transition: height 0.35s ease;
+ transition: height 0.35s ease;
+}
+
+.collapse.in {
+ height: auto;
+}
+
+.close {
+ float: right;
+ font-size: 20px;
+ font-weight: bold;
+ line-height: 20px;
+ color: #000000;
+ text-shadow: 0 1px 0 #ffffff;
+ opacity: 0.2;
+ filter: alpha(opacity=20);
+}
+
+.close:hover {
+ color: #000000;
+ text-decoration: none;
+ cursor: pointer;
+ opacity: 0.4;
+ filter: alpha(opacity=40);
+}
+
+button.close {
+ padding: 0;
+ cursor: pointer;
+ background: transparent;
+ border: 0;
+ -webkit-appearance: none;
+}
+
+.btn {
+ display: inline-block;
+ *display: inline;
+ padding: 4px 12px;
+ margin-bottom: 0;
+ *margin-left: .3em;
+ font-size: 14px;
+ line-height: 20px;
+ *line-height: 20px;
+ color: #333333;
+ text-align: center;
+ text-shadow: 0 1px 1px rgba(255, 255, 255, 0.75);
+ vertical-align: middle;
+ cursor: pointer;
+ background-color: #f5f5f5;
+ *background-color: #e6e6e6;
+ background-image: -moz-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));
+ background-image: -webkit-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: -o-linear-gradient(top, #ffffff, #e6e6e6);
+ background-image: linear-gradient(to bottom, #ffffff, #e6e6e6);
+ background-repeat: repeat-x;
+ border: 1px solid #bbbbbb;
+ *border: 0;
+ border-color: #e6e6e6 #e6e6e6 #bfbfbf;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ border-bottom-color: #a2a2a2;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ *zoom: 1;
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn:hover,
+.btn:active,
+.btn.active,
+.btn.disabled,
+.btn[disabled] {
+ color: #333333;
+ background-color: #e6e6e6;
+ *background-color: #d9d9d9;
+}
+
+.btn:active,
+.btn.active {
+ background-color: #cccccc \9;
+}
+
+.btn:first-child {
+ *margin-left: 0;
+}
+
+.btn:hover {
+ color: #333333;
+ text-decoration: none;
+ background-color: #e6e6e6;
+ *background-color: #d9d9d9;
+ /* Buttons in IE7 don't get borders, so darken on hover */
+
+ background-position: 0 -15px;
+ -webkit-transition: background-position 0.1s linear;
+ -moz-transition: background-position 0.1s linear;
+ -o-transition: background-position 0.1s linear;
+ transition: background-position 0.1s linear;
+}
+
+.btn:focus {
+ outline: thin dotted #333;
+ outline: 5px auto -webkit-focus-ring-color;
+ outline-offset: -2px;
+}
+
+.btn.active,
+.btn:active {
+ background-color: #e6e6e6;
+ background-color: #d9d9d9 \9;
+ background-image: none;
+ outline: 0;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn.disabled,
+.btn[disabled] {
+ cursor: default;
+ background-color: #e6e6e6;
+ background-image: none;
+ opacity: 0.65;
+ filter: alpha(opacity=65);
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-large {
+ padding: 11px 19px;
+ font-size: 17.5px;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.btn-large [class^="icon-"],
+.btn-large [class*=" icon-"] {
+ margin-top: 2px;
+}
+
+.btn-small {
+ padding: 2px 10px;
+ font-size: 11.9px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.btn-small [class^="icon-"],
+.btn-small [class*=" icon-"] {
+ margin-top: 0;
+}
+
+.btn-mini {
+ padding: 1px 6px;
+ font-size: 10.5px;
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.btn-block {
+ display: block;
+ width: 100%;
+ padding-right: 0;
+ padding-left: 0;
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+}
+
+.btn-block + .btn-block {
+ margin-top: 5px;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+ width: 100%;
+}
+
+.btn-primary.active,
+.btn-warning.active,
+.btn-danger.active,
+.btn-success.active,
+.btn-info.active,
+.btn-inverse.active {
+ color: rgba(255, 255, 255, 0.75);
+}
+
+.btn {
+ border-color: #c5c5c5;
+ border-color: rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);
+}
+
+.btn-primary {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #006dcc;
+ *background-color: #0044cc;
+ background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
+ background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
+ background-image: -o-linear-gradient(top, #0088cc, #0044cc);
+ background-image: linear-gradient(to bottom, #0088cc, #0044cc);
+ background-repeat: repeat-x;
+ border-color: #0044cc #0044cc #002a80;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-primary:hover,
+.btn-primary:active,
+.btn-primary.active,
+.btn-primary.disabled,
+.btn-primary[disabled] {
+ color: #ffffff;
+ background-color: #0044cc;
+ *background-color: #003bb3;
+}
+
+.btn-primary:active,
+.btn-primary.active {
+ background-color: #003399 \9;
+}
+
+.btn-warning {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #faa732;
+ *background-color: #f89406;
+ background-image: -moz-linear-gradient(top, #fbb450, #f89406);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image: -o-linear-gradient(top, #fbb450, #f89406);
+ background-image: linear-gradient(to bottom, #fbb450, #f89406);
+ background-repeat: repeat-x;
+ border-color: #f89406 #f89406 #ad6704;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-warning:hover,
+.btn-warning:active,
+.btn-warning.active,
+.btn-warning.disabled,
+.btn-warning[disabled] {
+ color: #ffffff;
+ background-color: #f89406;
+ *background-color: #df8505;
+}
+
+.btn-warning:active,
+.btn-warning.active {
+ background-color: #c67605 \9;
+}
+
+.btn-danger {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #da4f49;
+ *background-color: #bd362f;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: -o-linear-gradient(top, #ee5f5b, #bd362f);
+ background-image: linear-gradient(to bottom, #ee5f5b, #bd362f);
+ background-repeat: repeat-x;
+ border-color: #bd362f #bd362f #802420;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-danger:hover,
+.btn-danger:active,
+.btn-danger.active,
+.btn-danger.disabled,
+.btn-danger[disabled] {
+ color: #ffffff;
+ background-color: #bd362f;
+ *background-color: #a9302a;
+}
+
+.btn-danger:active,
+.btn-danger.active {
+ background-color: #942a25 \9;
+}
+
+.btn-success {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #5bb75b;
+ *background-color: #51a351;
+ background-image: -moz-linear-gradient(top, #62c462, #51a351);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));
+ background-image: -webkit-linear-gradient(top, #62c462, #51a351);
+ background-image: -o-linear-gradient(top, #62c462, #51a351);
+ background-image: linear-gradient(to bottom, #62c462, #51a351);
+ background-repeat: repeat-x;
+ border-color: #51a351 #51a351 #387038;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-success:hover,
+.btn-success:active,
+.btn-success.active,
+.btn-success.disabled,
+.btn-success[disabled] {
+ color: #ffffff;
+ background-color: #51a351;
+ *background-color: #499249;
+}
+
+.btn-success:active,
+.btn-success.active {
+ background-color: #408140 \9;
+}
+
+.btn-info {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #49afcd;
+ *background-color: #2f96b4;
+ background-image: -moz-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));
+ background-image: -webkit-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: -o-linear-gradient(top, #5bc0de, #2f96b4);
+ background-image: linear-gradient(to bottom, #5bc0de, #2f96b4);
+ background-repeat: repeat-x;
+ border-color: #2f96b4 #2f96b4 #1f6377;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-info:hover,
+.btn-info:active,
+.btn-info.active,
+.btn-info.disabled,
+.btn-info[disabled] {
+ color: #ffffff;
+ background-color: #2f96b4;
+ *background-color: #2a85a0;
+}
+
+.btn-info:active,
+.btn-info.active {
+ background-color: #24748c \9;
+}
+
+.btn-inverse {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #363636;
+ *background-color: #222222;
+ background-image: -moz-linear-gradient(top, #444444, #222222);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));
+ background-image: -webkit-linear-gradient(top, #444444, #222222);
+ background-image: -o-linear-gradient(top, #444444, #222222);
+ background-image: linear-gradient(to bottom, #444444, #222222);
+ background-repeat: repeat-x;
+ border-color: #222222 #222222 #000000;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.btn-inverse:hover,
+.btn-inverse:active,
+.btn-inverse.active,
+.btn-inverse.disabled,
+.btn-inverse[disabled] {
+ color: #ffffff;
+ background-color: #222222;
+ *background-color: #151515;
+}
+
+.btn-inverse:active,
+.btn-inverse.active {
+ background-color: #080808 \9;
+}
+
+button.btn,
+input[type="submit"].btn {
+ *padding-top: 3px;
+ *padding-bottom: 3px;
+}
+
+button.btn::-moz-focus-inner,
+input[type="submit"].btn::-moz-focus-inner {
+ padding: 0;
+ border: 0;
+}
+
+button.btn.btn-large,
+input[type="submit"].btn.btn-large {
+ *padding-top: 7px;
+ *padding-bottom: 7px;
+}
+
+button.btn.btn-small,
+input[type="submit"].btn.btn-small {
+ *padding-top: 3px;
+ *padding-bottom: 3px;
+}
+
+button.btn.btn-mini,
+input[type="submit"].btn.btn-mini {
+ *padding-top: 1px;
+ *padding-bottom: 1px;
+}
+
+.btn-link,
+.btn-link:active,
+.btn-link[disabled] {
+ background-color: transparent;
+ background-image: none;
+ -webkit-box-shadow: none;
+ -moz-box-shadow: none;
+ box-shadow: none;
+}
+
+.btn-link {
+ color: #0088cc;
+ cursor: pointer;
+ border-color: transparent;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-link:hover {
+ color: #005580;
+ text-decoration: underline;
+ background-color: transparent;
+}
+
+.btn-link[disabled]:hover {
+ color: #333333;
+ text-decoration: none;
+}
+
+.btn-group {
+ position: relative;
+ display: inline-block;
+ *display: inline;
+ *margin-left: .3em;
+ font-size: 0;
+ white-space: nowrap;
+ vertical-align: middle;
+ *zoom: 1;
+}
+
+.btn-group:first-child {
+ *margin-left: 0;
+}
+
+.btn-group + .btn-group {
+ margin-left: 5px;
+}
+
+.btn-toolbar {
+ margin-top: 10px;
+ margin-bottom: 10px;
+ font-size: 0;
+}
+
+.btn-toolbar .btn + .btn,
+.btn-toolbar .btn-group + .btn,
+.btn-toolbar .btn + .btn-group {
+ margin-left: 5px;
+}
+
+.btn-group > .btn {
+ position: relative;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-group > .btn + .btn {
+ margin-left: -1px;
+}
+
+.btn-group > .btn,
+.btn-group > .dropdown-menu {
+ font-size: 14px;
+}
+
+.btn-group > .btn-mini {
+ font-size: 11px;
+}
+
+.btn-group > .btn-small {
+ font-size: 12px;
+}
+
+.btn-group > .btn-large {
+ font-size: 16px;
+}
+
+.btn-group > .btn:first-child {
+ margin-left: 0;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.btn-group > .btn:last-child,
+.btn-group > .dropdown-toggle {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.btn-group > .btn.large:first-child {
+ margin-left: 0;
+ -webkit-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -webkit-border-top-left-radius: 6px;
+ border-top-left-radius: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topleft: 6px;
+}
+
+.btn-group > .btn.large:last-child,
+.btn-group > .large.dropdown-toggle {
+ -webkit-border-top-right-radius: 6px;
+ border-top-right-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 6px;
+}
+
+.btn-group > .btn:hover,
+.btn-group > .btn:focus,
+.btn-group > .btn:active,
+.btn-group > .btn.active {
+ z-index: 2;
+}
+
+.btn-group .dropdown-toggle:active,
+.btn-group.open .dropdown-toggle {
+ outline: 0;
+}
+
+.btn-group > .btn + .dropdown-toggle {
+ *padding-top: 5px;
+ padding-right: 8px;
+ *padding-bottom: 5px;
+ padding-left: 8px;
+ -webkit-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 1px 0 0 rgba(255, 255, 255, 0.125), inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn-group > .btn-mini + .dropdown-toggle {
+ *padding-top: 2px;
+ padding-right: 5px;
+ *padding-bottom: 2px;
+ padding-left: 5px;
+}
+
+.btn-group > .btn-small + .dropdown-toggle {
+ *padding-top: 5px;
+ *padding-bottom: 4px;
+}
+
+.btn-group > .btn-large + .dropdown-toggle {
+ *padding-top: 7px;
+ padding-right: 12px;
+ *padding-bottom: 7px;
+ padding-left: 12px;
+}
+
+.btn-group.open .dropdown-toggle {
+ background-image: none;
+ -webkit-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.btn-group.open .btn.dropdown-toggle {
+ background-color: #e6e6e6;
+}
+
+.btn-group.open .btn-primary.dropdown-toggle {
+ background-color: #0044cc;
+}
+
+.btn-group.open .btn-warning.dropdown-toggle {
+ background-color: #f89406;
+}
+
+.btn-group.open .btn-danger.dropdown-toggle {
+ background-color: #bd362f;
+}
+
+.btn-group.open .btn-success.dropdown-toggle {
+ background-color: #51a351;
+}
+
+.btn-group.open .btn-info.dropdown-toggle {
+ background-color: #2f96b4;
+}
+
+.btn-group.open .btn-inverse.dropdown-toggle {
+ background-color: #222222;
+}
+
+.btn .caret {
+ margin-top: 8px;
+ margin-left: 0;
+}
+
+.btn-mini .caret,
+.btn-small .caret,
+.btn-large .caret {
+ margin-top: 6px;
+}
+
+.btn-large .caret {
+ border-top-width: 5px;
+ border-right-width: 5px;
+ border-left-width: 5px;
+}
+
+.dropup .btn-large .caret {
+ border-bottom-width: 5px;
+}
+
+.btn-primary .caret,
+.btn-warning .caret,
+.btn-danger .caret,
+.btn-info .caret,
+.btn-success .caret,
+.btn-inverse .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+}
+
+.btn-group-vertical {
+ display: inline-block;
+ *display: inline;
+ /* IE7 inline-block hack */
+
+ *zoom: 1;
+}
+
+.btn-group-vertical .btn {
+ display: block;
+ float: none;
+ width: 100%;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.btn-group-vertical .btn + .btn {
+ margin-top: -1px;
+ margin-left: 0;
+}
+
+.btn-group-vertical .btn:first-child {
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+
+.btn-group-vertical .btn:last-child {
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+
+.btn-group-vertical .btn-large:first-child {
+ -webkit-border-radius: 6px 6px 0 0;
+ -moz-border-radius: 6px 6px 0 0;
+ border-radius: 6px 6px 0 0;
+}
+
+.btn-group-vertical .btn-large:last-child {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+}
+
+.alert {
+ padding: 8px 35px 8px 14px;
+ margin-bottom: 20px;
+ color: #c09853;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ background-color: #fcf8e3;
+ border: 1px solid #fbeed5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.alert h4 {
+ margin: 0;
+}
+
+.alert .close {
+ position: relative;
+ top: -2px;
+ right: -21px;
+ line-height: 20px;
+}
+
+.alert-success {
+ color: #468847;
+ background-color: #dff0d8;
+ border-color: #d6e9c6;
+}
+
+.alert-danger,
+.alert-error {
+ color: #b94a48;
+ background-color: #f2dede;
+ border-color: #eed3d7;
+}
+
+.alert-info {
+ color: #3a87ad;
+ background-color: #d9edf7;
+ border-color: #bce8f1;
+}
+
+.alert-block {
+ padding-top: 14px;
+ padding-bottom: 14px;
+}
+
+.alert-block > p,
+.alert-block > ul {
+ margin-bottom: 0;
+}
+
+.alert-block p + p {
+ margin-top: 5px;
+}
+
+.nav {
+ margin-bottom: 20px;
+ margin-left: 0;
+ list-style: none;
+}
+
+.nav > li > a {
+ display: block;
+}
+
+.nav > li > a:hover {
+ text-decoration: none;
+ background-color: #eeeeee;
+}
+
+.nav > .pull-right {
+ float: right;
+}
+
+.nav-header {
+ display: block;
+ padding: 3px 15px;
+ font-size: 11px;
+ font-weight: bold;
+ line-height: 20px;
+ color: #999999;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+ text-transform: uppercase;
+}
+
+.nav li + .nav-header {
+ margin-top: 9px;
+}
+
+.nav-list {
+ padding-right: 15px;
+ padding-left: 15px;
+ margin-bottom: 0;
+}
+
+.nav-list > li > a,
+.nav-list .nav-header {
+ margin-right: -15px;
+ margin-left: -15px;
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
+}
+
+.nav-list > li > a {
+ padding: 3px 15px;
+}
+
+.nav-list > .active > a,
+.nav-list > .active > a:hover {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.2);
+ background-color: #0088cc;
+}
+
+.nav-list [class^="icon-"],
+.nav-list [class*=" icon-"] {
+ margin-right: 2px;
+}
+
+.nav-list .divider {
+ *width: 100%;
+ height: 1px;
+ margin: 9px 1px;
+ *margin: -5px 0 5px;
+ overflow: hidden;
+ background-color: #e5e5e5;
+ border-bottom: 1px solid #ffffff;
+}
+
+.nav-tabs,
+.nav-pills {
+ *zoom: 1;
+}
+
+.nav-tabs:before,
+.nav-pills:before,
+.nav-tabs:after,
+.nav-pills:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.nav-tabs:after,
+.nav-pills:after {
+ clear: both;
+}
+
+.nav-tabs > li,
+.nav-pills > li {
+ float: left;
+}
+
+.nav-tabs > li > a,
+.nav-pills > li > a {
+ padding-right: 12px;
+ padding-left: 12px;
+ margin-right: 2px;
+ line-height: 14px;
+}
+
+.nav-tabs {
+ border-bottom: 1px solid #ddd;
+}
+
+.nav-tabs > li {
+ margin-bottom: -1px;
+}
+
+.nav-tabs > li > a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ line-height: 20px;
+ border: 1px solid transparent;
+ -webkit-border-radius: 4px 4px 0 0;
+ -moz-border-radius: 4px 4px 0 0;
+ border-radius: 4px 4px 0 0;
+}
+
+.nav-tabs > li > a:hover {
+ border-color: #eeeeee #eeeeee #dddddd;
+}
+
+.nav-tabs > .active > a,
+.nav-tabs > .active > a:hover {
+ color: #555555;
+ cursor: default;
+ background-color: #ffffff;
+ border: 1px solid #ddd;
+ border-bottom-color: transparent;
+}
+
+.nav-pills > li > a {
+ padding-top: 8px;
+ padding-bottom: 8px;
+ margin-top: 2px;
+ margin-bottom: 2px;
+ -webkit-border-radius: 5px;
+ -moz-border-radius: 5px;
+ border-radius: 5px;
+}
+
+.nav-pills > .active > a,
+.nav-pills > .active > a:hover {
+ color: #ffffff;
+ background-color: #0088cc;
+}
+
+.nav-stacked > li {
+ float: none;
+}
+
+.nav-stacked > li > a {
+ margin-right: 0;
+}
+
+.nav-tabs.nav-stacked {
+ border-bottom: 0;
+}
+
+.nav-tabs.nav-stacked > li > a {
+ border: 1px solid #ddd;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.nav-tabs.nav-stacked > li:first-child > a {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.nav-tabs.nav-stacked > li:last-child > a {
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -moz-border-radius-bottomright: 4px;
+ -moz-border-radius-bottomleft: 4px;
+}
+
+.nav-tabs.nav-stacked > li > a:hover {
+ z-index: 2;
+ border-color: #ddd;
+}
+
+.nav-pills.nav-stacked > li > a {
+ margin-bottom: 3px;
+}
+
+.nav-pills.nav-stacked > li:last-child > a {
+ margin-bottom: 1px;
+}
+
+.nav-tabs .dropdown-menu {
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+}
+
+.nav-pills .dropdown-menu {
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.nav .dropdown-toggle .caret {
+ margin-top: 6px;
+ border-top-color: #0088cc;
+ border-bottom-color: #0088cc;
+}
+
+.nav .dropdown-toggle:hover .caret {
+ border-top-color: #005580;
+ border-bottom-color: #005580;
+}
+
+/* move down carets for tabs */
+
+.nav-tabs .dropdown-toggle .caret {
+ margin-top: 8px;
+}
+
+.nav .active .dropdown-toggle .caret {
+ border-top-color: #fff;
+ border-bottom-color: #fff;
+}
+
+.nav-tabs .active .dropdown-toggle .caret {
+ border-top-color: #555555;
+ border-bottom-color: #555555;
+}
+
+.nav > .dropdown.active > a:hover {
+ cursor: pointer;
+}
+
+.nav-tabs .open .dropdown-toggle,
+.nav-pills .open .dropdown-toggle,
+.nav > li.dropdown.open.active > a:hover {
+ color: #ffffff;
+ background-color: #999999;
+ border-color: #999999;
+}
+
+.nav li.dropdown.open .caret,
+.nav li.dropdown.open.active .caret,
+.nav li.dropdown.open a:hover .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+ opacity: 1;
+ filter: alpha(opacity=100);
+}
+
+.tabs-stacked .open > a:hover {
+ border-color: #999999;
+}
+
+.tabbable {
+ *zoom: 1;
+}
+
+.tabbable:before,
+.tabbable:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.tabbable:after {
+ clear: both;
+}
+
+.tab-content {
+ overflow: auto;
+}
+
+.tabs-below > .nav-tabs,
+.tabs-right > .nav-tabs,
+.tabs-left > .nav-tabs {
+ border-bottom: 0;
+}
+
+.tab-content > .tab-pane,
+.pill-content > .pill-pane {
+ display: none;
+}
+
+.tab-content > .active,
+.pill-content > .active {
+ display: block;
+}
+
+.tabs-below > .nav-tabs {
+ border-top: 1px solid #ddd;
+}
+
+.tabs-below > .nav-tabs > li {
+ margin-top: -1px;
+ margin-bottom: 0;
+}
+
+.tabs-below > .nav-tabs > li > a {
+ -webkit-border-radius: 0 0 4px 4px;
+ -moz-border-radius: 0 0 4px 4px;
+ border-radius: 0 0 4px 4px;
+}
+
+.tabs-below > .nav-tabs > li > a:hover {
+ border-top-color: #ddd;
+ border-bottom-color: transparent;
+}
+
+.tabs-below > .nav-tabs > .active > a,
+.tabs-below > .nav-tabs > .active > a:hover {
+ border-color: transparent #ddd #ddd #ddd;
+}
+
+.tabs-left > .nav-tabs > li,
+.tabs-right > .nav-tabs > li {
+ float: none;
+}
+
+.tabs-left > .nav-tabs > li > a,
+.tabs-right > .nav-tabs > li > a {
+ min-width: 74px;
+ margin-right: 0;
+ margin-bottom: 3px;
+}
+
+.tabs-left > .nav-tabs {
+ float: left;
+ margin-right: 19px;
+ border-right: 1px solid #ddd;
+}
+
+.tabs-left > .nav-tabs > li > a {
+ margin-right: -1px;
+ -webkit-border-radius: 4px 0 0 4px;
+ -moz-border-radius: 4px 0 0 4px;
+ border-radius: 4px 0 0 4px;
+}
+
+.tabs-left > .nav-tabs > li > a:hover {
+ border-color: #eeeeee #dddddd #eeeeee #eeeeee;
+}
+
+.tabs-left > .nav-tabs .active > a,
+.tabs-left > .nav-tabs .active > a:hover {
+ border-color: #ddd transparent #ddd #ddd;
+ *border-right-color: #ffffff;
+}
+
+.tabs-right > .nav-tabs {
+ float: right;
+ margin-left: 19px;
+ border-left: 1px solid #ddd;
+}
+
+.tabs-right > .nav-tabs > li > a {
+ margin-left: -1px;
+ -webkit-border-radius: 0 4px 4px 0;
+ -moz-border-radius: 0 4px 4px 0;
+ border-radius: 0 4px 4px 0;
+}
+
+.tabs-right > .nav-tabs > li > a:hover {
+ border-color: #eeeeee #eeeeee #eeeeee #dddddd;
+}
+
+.tabs-right > .nav-tabs .active > a,
+.tabs-right > .nav-tabs .active > a:hover {
+ border-color: #ddd #ddd #ddd transparent;
+ *border-left-color: #ffffff;
+}
+
+.nav > .disabled > a {
+ color: #999999;
+}
+
+.nav > .disabled > a:hover {
+ text-decoration: none;
+ cursor: default;
+ background-color: transparent;
+}
+
+.navbar {
+ *position: relative;
+ *z-index: 2;
+ margin-bottom: 20px;
+ overflow: visible;
+ color: #777777;
+}
+
+.navbar-inner {
+ min-height: 40px;
+ padding-right: 20px;
+ padding-left: 20px;
+ background-color: #fafafa;
+ background-image: -moz-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));
+ background-image: -webkit-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: -o-linear-gradient(top, #ffffff, #f2f2f2);
+ background-image: linear-gradient(to bottom, #ffffff, #f2f2f2);
+ background-repeat: repeat-x;
+ border: 1px solid #d4d4d4;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);
+ *zoom: 1;
+ -webkit-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+ -moz-box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.065);
+}
+
+.navbar-inner:before,
+.navbar-inner:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.navbar-inner:after {
+ clear: both;
+}
+
+.navbar .container {
+ width: auto;
+}
+
+.nav-collapse.collapse {
+ height: auto;
+ overflow: visible;
+}
+
+.navbar .brand {
+ display: block;
+ float: left;
+ padding: 10px 20px 10px;
+ margin-left: -20px;
+ font-size: 20px;
+ font-weight: 200;
+ color: #777777;
+ text-shadow: 0 1px 0 #ffffff;
+}
+
+.navbar .brand:hover {
+ text-decoration: none;
+}
+
+.navbar-text {
+ margin-bottom: 0;
+ line-height: 40px;
+}
+
+.navbar-link {
+ color: #777777;
+}
+
+.navbar-link:hover {
+ color: #333333;
+}
+
+.navbar .divider-vertical {
+ height: 40px;
+ margin: 0 9px;
+ border-right: 1px solid #ffffff;
+ border-left: 1px solid #f2f2f2;
+}
+
+.navbar .btn,
+.navbar .btn-group {
+ margin-top: 5px;
+}
+
+.navbar .btn-group .btn,
+.navbar .input-prepend .btn,
+.navbar .input-append .btn {
+ margin-top: 0;
+}
+
+.navbar-form {
+ margin-bottom: 0;
+ *zoom: 1;
+}
+
+.navbar-form:before,
+.navbar-form:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.navbar-form:after {
+ clear: both;
+}
+
+.navbar-form input,
+.navbar-form select,
+.navbar-form .radio,
+.navbar-form .checkbox {
+ margin-top: 5px;
+}
+
+.navbar-form input,
+.navbar-form select,
+.navbar-form .btn {
+ display: inline-block;
+ margin-bottom: 0;
+}
+
+.navbar-form input[type="image"],
+.navbar-form input[type="checkbox"],
+.navbar-form input[type="radio"] {
+ margin-top: 3px;
+}
+
+.navbar-form .input-append,
+.navbar-form .input-prepend {
+ margin-top: 6px;
+ white-space: nowrap;
+}
+
+.navbar-form .input-append input,
+.navbar-form .input-prepend input {
+ margin-top: 0;
+}
+
+.navbar-search {
+ position: relative;
+ float: left;
+ margin-top: 5px;
+ margin-bottom: 0;
+}
+
+.navbar-search .search-query {
+ padding: 4px 14px;
+ margin-bottom: 0;
+ font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
+ font-size: 13px;
+ font-weight: normal;
+ line-height: 1;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+.navbar-static-top {
+ position: static;
+ margin-bottom: 0;
+}
+
+.navbar-static-top .navbar-inner {
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.navbar-fixed-top,
+.navbar-fixed-bottom {
+ position: fixed;
+ right: 0;
+ left: 0;
+ z-index: 1030;
+ margin-bottom: 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ border-width: 0 0 1px;
+}
+
+.navbar-fixed-bottom .navbar-inner {
+ border-width: 1px 0 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-fixed-bottom .navbar-inner {
+ padding-right: 0;
+ padding-left: 0;
+ -webkit-border-radius: 0;
+ -moz-border-radius: 0;
+ border-radius: 0;
+}
+
+.navbar-static-top .container,
+.navbar-fixed-top .container,
+.navbar-fixed-bottom .container {
+ width: 940px;
+}
+
+.navbar-fixed-top {
+ top: 0;
+}
+
+.navbar-fixed-top .navbar-inner,
+.navbar-static-top .navbar-inner {
+ -webkit-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 1px 10px rgba(0, 0, 0, 0.1);
+}
+
+.navbar-fixed-bottom {
+ bottom: 0;
+}
+
+.navbar-fixed-bottom .navbar-inner {
+ -webkit-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+ box-shadow: 0 -1px 10px rgba(0, 0, 0, 0.1);
+}
+
+.navbar .nav {
+ position: relative;
+ left: 0;
+ display: block;
+ float: left;
+ margin: 0 10px 0 0;
+}
+
+.navbar .nav.pull-right {
+ float: right;
+ margin-right: 0;
+}
+
+.navbar .nav > li {
+ float: left;
+}
+
+.navbar .nav > li > a {
+ float: none;
+ padding: 10px 15px 10px;
+ color: #777777;
+ text-decoration: none;
+ text-shadow: 0 1px 0 #ffffff;
+}
+
+.navbar .nav .dropdown-toggle .caret {
+ margin-top: 8px;
+}
+
+.navbar .nav > li > a:focus,
+.navbar .nav > li > a:hover {
+ color: #333333;
+ text-decoration: none;
+ background-color: transparent;
+}
+
+.navbar .nav > .active > a,
+.navbar .nav > .active > a:hover,
+.navbar .nav > .active > a:focus {
+ color: #555555;
+ text-decoration: none;
+ background-color: #e5e5e5;
+ -webkit-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+ -moz-box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+ box-shadow: inset 0 3px 8px rgba(0, 0, 0, 0.125);
+}
+
+.navbar .btn-navbar {
+ display: none;
+ float: right;
+ padding: 7px 10px;
+ margin-right: 5px;
+ margin-left: 5px;
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #ededed;
+ *background-color: #e5e5e5;
+ background-image: -moz-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));
+ background-image: -webkit-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: -o-linear-gradient(top, #f2f2f2, #e5e5e5);
+ background-image: linear-gradient(to bottom, #f2f2f2, #e5e5e5);
+ background-repeat: repeat-x;
+ border-color: #e5e5e5 #e5e5e5 #bfbfbf;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+ -webkit-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ -moz-box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+ box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.1), 0 1px 0 rgba(255, 255, 255, 0.075);
+}
+
+.navbar .btn-navbar:hover,
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active,
+.navbar .btn-navbar.disabled,
+.navbar .btn-navbar[disabled] {
+ color: #ffffff;
+ background-color: #e5e5e5;
+ *background-color: #d9d9d9;
+}
+
+.navbar .btn-navbar:active,
+.navbar .btn-navbar.active {
+ background-color: #cccccc \9;
+}
+
+.navbar .btn-navbar .icon-bar {
+ display: block;
+ width: 18px;
+ height: 2px;
+ background-color: #f5f5f5;
+ -webkit-border-radius: 1px;
+ -moz-border-radius: 1px;
+ border-radius: 1px;
+ -webkit-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+ -moz-box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+ box-shadow: 0 1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.btn-navbar .icon-bar + .icon-bar {
+ margin-top: 3px;
+}
+
+.navbar .nav > li > .dropdown-menu:before {
+ position: absolute;
+ top: -7px;
+ left: 9px;
+ display: inline-block;
+ border-right: 7px solid transparent;
+ border-bottom: 7px solid #ccc;
+ border-left: 7px solid transparent;
+ border-bottom-color: rgba(0, 0, 0, 0.2);
+ content: '';
+}
+
+.navbar .nav > li > .dropdown-menu:after {
+ position: absolute;
+ top: -6px;
+ left: 10px;
+ display: inline-block;
+ border-right: 6px solid transparent;
+ border-bottom: 6px solid #ffffff;
+ border-left: 6px solid transparent;
+ content: '';
+}
+
+.navbar-fixed-bottom .nav > li > .dropdown-menu:before {
+ top: auto;
+ bottom: -7px;
+ border-top: 7px solid #ccc;
+ border-bottom: 0;
+ border-top-color: rgba(0, 0, 0, 0.2);
+}
+
+.navbar-fixed-bottom .nav > li > .dropdown-menu:after {
+ top: auto;
+ bottom: -6px;
+ border-top: 6px solid #ffffff;
+ border-bottom: 0;
+}
+
+.navbar .nav li.dropdown.open > .dropdown-toggle,
+.navbar .nav li.dropdown.active > .dropdown-toggle,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle {
+ color: #555555;
+ background-color: #e5e5e5;
+}
+
+.navbar .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #777777;
+ border-bottom-color: #777777;
+}
+
+.navbar .nav li.dropdown.open > .dropdown-toggle .caret,
+.navbar .nav li.dropdown.active > .dropdown-toggle .caret,
+.navbar .nav li.dropdown.open.active > .dropdown-toggle .caret {
+ border-top-color: #555555;
+ border-bottom-color: #555555;
+}
+
+.navbar .pull-right > li > .dropdown-menu,
+.navbar .nav > li > .dropdown-menu.pull-right {
+ right: 0;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu:before,
+.navbar .nav > li > .dropdown-menu.pull-right:before {
+ right: 12px;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu:after,
+.navbar .nav > li > .dropdown-menu.pull-right:after {
+ right: 13px;
+ left: auto;
+}
+
+.navbar .pull-right > li > .dropdown-menu .dropdown-menu,
+.navbar .nav > li > .dropdown-menu.pull-right .dropdown-menu {
+ right: 100%;
+ left: auto;
+ margin-right: -1px;
+ margin-left: 0;
+ -webkit-border-radius: 6px 0 6px 6px;
+ -moz-border-radius: 6px 0 6px 6px;
+ border-radius: 6px 0 6px 6px;
+}
+
+.navbar-inverse {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-inner {
+ background-color: #1b1b1b;
+ background-image: -moz-linear-gradient(top, #222222, #111111);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));
+ background-image: -webkit-linear-gradient(top, #222222, #111111);
+ background-image: -o-linear-gradient(top, #222222, #111111);
+ background-image: linear-gradient(to bottom, #222222, #111111);
+ background-repeat: repeat-x;
+ border-color: #252525;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);
+}
+
+.navbar-inverse .brand,
+.navbar-inverse .nav > li > a {
+ color: #999999;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+}
+
+.navbar-inverse .brand:hover,
+.navbar-inverse .nav > li > a:hover {
+ color: #ffffff;
+}
+
+.navbar-inverse .nav > li > a:focus,
+.navbar-inverse .nav > li > a:hover {
+ color: #ffffff;
+ background-color: transparent;
+}
+
+.navbar-inverse .nav .active > a,
+.navbar-inverse .nav .active > a:hover,
+.navbar-inverse .nav .active > a:focus {
+ color: #ffffff;
+ background-color: #111111;
+}
+
+.navbar-inverse .navbar-link {
+ color: #999999;
+}
+
+.navbar-inverse .navbar-link:hover {
+ color: #ffffff;
+}
+
+.navbar-inverse .divider-vertical {
+ border-right-color: #222222;
+ border-left-color: #111111;
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle,
+.navbar-inverse .nav li.dropdown.active > .dropdown-toggle,
+.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle {
+ color: #ffffff;
+ background-color: #111111;
+}
+
+.navbar-inverse .nav li.dropdown > .dropdown-toggle .caret {
+ border-top-color: #999999;
+ border-bottom-color: #999999;
+}
+
+.navbar-inverse .nav li.dropdown.open > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown.active > .dropdown-toggle .caret,
+.navbar-inverse .nav li.dropdown.open.active > .dropdown-toggle .caret {
+ border-top-color: #ffffff;
+ border-bottom-color: #ffffff;
+}
+
+.navbar-inverse .navbar-search .search-query {
+ color: #ffffff;
+ background-color: #515151;
+ border-color: #111111;
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.15);
+ -webkit-transition: none;
+ -moz-transition: none;
+ -o-transition: none;
+ transition: none;
+}
+
+.navbar-inverse .navbar-search .search-query:-moz-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query:-ms-input-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder {
+ color: #cccccc;
+}
+
+.navbar-inverse .navbar-search .search-query:focus,
+.navbar-inverse .navbar-search .search-query.focused {
+ padding: 5px 15px;
+ color: #333333;
+ text-shadow: 0 1px 0 #ffffff;
+ background-color: #ffffff;
+ border: 0;
+ outline: 0;
+ -webkit-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+ box-shadow: 0 0 3px rgba(0, 0, 0, 0.15);
+}
+
+.navbar-inverse .btn-navbar {
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #0e0e0e;
+ *background-color: #040404;
+ background-image: -moz-linear-gradient(top, #151515, #040404);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));
+ background-image: -webkit-linear-gradient(top, #151515, #040404);
+ background-image: -o-linear-gradient(top, #151515, #040404);
+ background-image: linear-gradient(to bottom, #151515, #040404);
+ background-repeat: repeat-x;
+ border-color: #040404 #040404 #000000;
+ border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);
+ filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
+}
+
+.navbar-inverse .btn-navbar:hover,
+.navbar-inverse .btn-navbar:active,
+.navbar-inverse .btn-navbar.active,
+.navbar-inverse .btn-navbar.disabled,
+.navbar-inverse .btn-navbar[disabled] {
+ color: #ffffff;
+ background-color: #040404;
+ *background-color: #000000;
+}
+
+.navbar-inverse .btn-navbar:active,
+.navbar-inverse .btn-navbar.active {
+ background-color: #000000 \9;
+}
+
+.breadcrumb {
+ padding: 8px 15px;
+ margin: 0 0 20px;
+ list-style: none;
+ background-color: #f5f5f5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.breadcrumb li {
+ display: inline-block;
+ *display: inline;
+ text-shadow: 0 1px 0 #ffffff;
+ *zoom: 1;
+}
+
+.breadcrumb .divider {
+ padding: 0 5px;
+ color: #ccc;
+}
+
+.breadcrumb .active {
+ color: #999999;
+}
+
+.pagination {
+ margin: 20px 0;
+}
+
+.pagination ul {
+ display: inline-block;
+ *display: inline;
+ margin-bottom: 0;
+ margin-left: 0;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ *zoom: 1;
+ -webkit-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ -moz-box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
+}
+
+.pagination ul > li {
+ display: inline;
+}
+
+.pagination ul > li > a,
+.pagination ul > li > span {
+ float: left;
+ padding: 4px 12px;
+ line-height: 20px;
+ text-decoration: none;
+ background-color: #ffffff;
+ border: 1px solid #dddddd;
+ border-left-width: 0;
+}
+
+.pagination ul > li > a:hover,
+.pagination ul > .active > a,
+.pagination ul > .active > span {
+ background-color: #f5f5f5;
+}
+
+.pagination ul > .active > a,
+.pagination ul > .active > span {
+ color: #999999;
+ cursor: default;
+}
+
+.pagination ul > .disabled > span,
+.pagination ul > .disabled > a,
+.pagination ul > .disabled > a:hover {
+ color: #999999;
+ cursor: default;
+ background-color: transparent;
+}
+
+.pagination ul > li:first-child > a,
+.pagination ul > li:first-child > span {
+ border-left-width: 1px;
+ -webkit-border-bottom-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+ -webkit-border-top-left-radius: 4px;
+ border-top-left-radius: 4px;
+ -moz-border-radius-bottomleft: 4px;
+ -moz-border-radius-topleft: 4px;
+}
+
+.pagination ul > li:last-child > a,
+.pagination ul > li:last-child > span {
+ -webkit-border-top-right-radius: 4px;
+ border-top-right-radius: 4px;
+ -webkit-border-bottom-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ -moz-border-radius-topright: 4px;
+ -moz-border-radius-bottomright: 4px;
+}
+
+.pagination-centered {
+ text-align: center;
+}
+
+.pagination-right {
+ text-align: right;
+}
+
+.pagination-large ul > li > a,
+.pagination-large ul > li > span {
+ padding: 11px 19px;
+ font-size: 17.5px;
+}
+
+.pagination-large ul > li:first-child > a,
+.pagination-large ul > li:first-child > span {
+ -webkit-border-bottom-left-radius: 6px;
+ border-bottom-left-radius: 6px;
+ -webkit-border-top-left-radius: 6px;
+ border-top-left-radius: 6px;
+ -moz-border-radius-bottomleft: 6px;
+ -moz-border-radius-topleft: 6px;
+}
+
+.pagination-large ul > li:last-child > a,
+.pagination-large ul > li:last-child > span {
+ -webkit-border-top-right-radius: 6px;
+ border-top-right-radius: 6px;
+ -webkit-border-bottom-right-radius: 6px;
+ border-bottom-right-radius: 6px;
+ -moz-border-radius-topright: 6px;
+ -moz-border-radius-bottomright: 6px;
+}
+
+.pagination-mini ul > li:first-child > a,
+.pagination-small ul > li:first-child > a,
+.pagination-mini ul > li:first-child > span,
+.pagination-small ul > li:first-child > span {
+ -webkit-border-bottom-left-radius: 3px;
+ border-bottom-left-radius: 3px;
+ -webkit-border-top-left-radius: 3px;
+ border-top-left-radius: 3px;
+ -moz-border-radius-bottomleft: 3px;
+ -moz-border-radius-topleft: 3px;
+}
+
+.pagination-mini ul > li:last-child > a,
+.pagination-small ul > li:last-child > a,
+.pagination-mini ul > li:last-child > span,
+.pagination-small ul > li:last-child > span {
+ -webkit-border-top-right-radius: 3px;
+ border-top-right-radius: 3px;
+ -webkit-border-bottom-right-radius: 3px;
+ border-bottom-right-radius: 3px;
+ -moz-border-radius-topright: 3px;
+ -moz-border-radius-bottomright: 3px;
+}
+
+.pagination-small ul > li > a,
+.pagination-small ul > li > span {
+ padding: 2px 10px;
+ font-size: 11.9px;
+}
+
+.pagination-mini ul > li > a,
+.pagination-mini ul > li > span {
+ padding: 1px 6px;
+ font-size: 10.5px;
+}
+
+.pager {
+ margin: 20px 0;
+ text-align: center;
+ list-style: none;
+ *zoom: 1;
+}
+
+.pager:before,
+.pager:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.pager:after {
+ clear: both;
+}
+
+.pager li {
+ display: inline;
+}
+
+.pager li > a,
+.pager li > span {
+ display: inline-block;
+ padding: 5px 14px;
+ background-color: #fff;
+ border: 1px solid #ddd;
+ -webkit-border-radius: 15px;
+ -moz-border-radius: 15px;
+ border-radius: 15px;
+}
+
+.pager li > a:hover {
+ text-decoration: none;
+ background-color: #f5f5f5;
+}
+
+.pager .next > a,
+.pager .next > span {
+ float: right;
+}
+
+.pager .previous > a,
+.pager .previous > span {
+ float: left;
+}
+
+.pager .disabled > a,
+.pager .disabled > a:hover,
+.pager .disabled > span {
+ color: #999999;
+ cursor: default;
+ background-color: #fff;
+}
+
+.modal-backdrop {
+ position: fixed;
+ top: 0;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ z-index: 1040;
+ background-color: #000000;
+}
+
+.modal-backdrop.fade {
+ opacity: 0;
+}
+
+.modal-backdrop,
+.modal-backdrop.fade.in {
+ opacity: 0.8;
+ filter: alpha(opacity=80);
+}
+
+.modal {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ z-index: 1050;
+ width: 560px;
+ margin: -250px 0 0 -280px;
+ background-color: #ffffff;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, 0.3);
+ *border: 1px solid #999;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ outline: none;
+ -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding-box;
+ background-clip: padding-box;
+}
+
+.modal.fade {
+ top: -25%;
+ -webkit-transition: opacity 0.3s linear, top 0.3s ease-out;
+ -moz-transition: opacity 0.3s linear, top 0.3s ease-out;
+ -o-transition: opacity 0.3s linear, top 0.3s ease-out;
+ transition: opacity 0.3s linear, top 0.3s ease-out;
+}
+
+.modal.fade.in {
+ top: 50%;
+}
+
+.modal-header {
+ padding: 9px 15px;
+ border-bottom: 1px solid #eee;
+}
+
+.modal-header .close {
+ margin-top: 2px;
+}
+
+.modal-header h3 {
+ margin: 0;
+ line-height: 30px;
+}
+
+.modal-body {
+ max-height: 400px;
+ padding: 15px;
+ overflow-y: auto;
+}
+
+.modal-form {
+ margin-bottom: 0;
+}
+
+.modal-footer {
+ padding: 14px 15px 15px;
+ margin-bottom: 0;
+ text-align: right;
+ background-color: #f5f5f5;
+ border-top: 1px solid #ddd;
+ -webkit-border-radius: 0 0 6px 6px;
+ -moz-border-radius: 0 0 6px 6px;
+ border-radius: 0 0 6px 6px;
+ *zoom: 1;
+ -webkit-box-shadow: inset 0 1px 0 #ffffff;
+ -moz-box-shadow: inset 0 1px 0 #ffffff;
+ box-shadow: inset 0 1px 0 #ffffff;
+}
+
+.modal-footer:before,
+.modal-footer:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.modal-footer:after {
+ clear: both;
+}
+
+.modal-footer .btn + .btn {
+ margin-bottom: 0;
+ margin-left: 5px;
+}
+
+.modal-footer .btn-group .btn + .btn {
+ margin-left: -1px;
+}
+
+.modal-footer .btn-block + .btn-block {
+ margin-left: 0;
+}
+
+.tooltip {
+ position: absolute;
+ z-index: 1030;
+ display: block;
+ padding: 5px;
+ font-size: 11px;
+ opacity: 0;
+ filter: alpha(opacity=0);
+ visibility: visible;
+}
+
+.tooltip.in {
+ opacity: 0.8;
+ filter: alpha(opacity=80);
+}
+
+.tooltip.top {
+ margin-top: -3px;
+}
+
+.tooltip.right {
+ margin-left: 3px;
+}
+
+.tooltip.bottom {
+ margin-top: 3px;
+}
+
+.tooltip.left {
+ margin-left: -3px;
+}
+
+.tooltip-inner {
+ max-width: 200px;
+ padding: 3px 8px;
+ color: #ffffff;
+ text-align: center;
+ text-decoration: none;
+ background-color: #000000;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.tooltip.top .tooltip-arrow {
+ bottom: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-top-color: #000000;
+ border-width: 5px 5px 0;
+}
+
+.tooltip.right .tooltip-arrow {
+ top: 50%;
+ left: 0;
+ margin-top: -5px;
+ border-right-color: #000000;
+ border-width: 5px 5px 5px 0;
+}
+
+.tooltip.left .tooltip-arrow {
+ top: 50%;
+ right: 0;
+ margin-top: -5px;
+ border-left-color: #000000;
+ border-width: 5px 0 5px 5px;
+}
+
+.tooltip.bottom .tooltip-arrow {
+ top: 0;
+ left: 50%;
+ margin-left: -5px;
+ border-bottom-color: #000000;
+ border-width: 0 5px 5px;
+}
+
+.popover {
+ position: absolute;
+ top: 0;
+ left: 0;
+ z-index: 1010;
+ display: none;
+ width: 236px;
+ padding: 1px;
+ background-color: #ffffff;
+ border: 1px solid #ccc;
+ border: 1px solid rgba(0, 0, 0, 0.2);
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding;
+ background-clip: padding-box;
+}
+
+.popover.top {
+ margin-top: -10px;
+}
+
+.popover.right {
+ margin-left: 10px;
+}
+
+.popover.bottom {
+ margin-top: 10px;
+}
+
+.popover.left {
+ margin-left: -10px;
+}
+
+.popover-title {
+ padding: 8px 14px;
+ margin: 0;
+ font-size: 14px;
+ font-weight: normal;
+ line-height: 18px;
+ background-color: #f7f7f7;
+ border-bottom: 1px solid #ebebeb;
+ -webkit-border-radius: 5px 5px 0 0;
+ -moz-border-radius: 5px 5px 0 0;
+ border-radius: 5px 5px 0 0;
+}
+
+.popover-content {
+ padding: 9px 14px;
+}
+
+.popover-content p,
+.popover-content ul,
+.popover-content ol {
+ margin-bottom: 0;
+}
+
+.popover .arrow,
+.popover .arrow:after {
+ position: absolute;
+ display: inline-block;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.popover .arrow:after {
+ z-index: -1;
+ content: "";
+}
+
+.popover.top .arrow {
+ bottom: -10px;
+ left: 50%;
+ margin-left: -10px;
+ border-top-color: #ffffff;
+ border-width: 10px 10px 0;
+}
+
+.popover.top .arrow:after {
+ bottom: -1px;
+ left: -11px;
+ border-top-color: rgba(0, 0, 0, 0.25);
+ border-width: 11px 11px 0;
+}
+
+.popover.right .arrow {
+ top: 50%;
+ left: -10px;
+ margin-top: -10px;
+ border-right-color: #ffffff;
+ border-width: 10px 10px 10px 0;
+}
+
+.popover.right .arrow:after {
+ bottom: -11px;
+ left: -1px;
+ border-right-color: rgba(0, 0, 0, 0.25);
+ border-width: 11px 11px 11px 0;
+}
+
+.popover.bottom .arrow {
+ top: -10px;
+ left: 50%;
+ margin-left: -10px;
+ border-bottom-color: #ffffff;
+ border-width: 0 10px 10px;
+}
+
+.popover.bottom .arrow:after {
+ top: -1px;
+ left: -11px;
+ border-bottom-color: rgba(0, 0, 0, 0.25);
+ border-width: 0 11px 11px;
+}
+
+.popover.left .arrow {
+ top: 50%;
+ right: -10px;
+ margin-top: -10px;
+ border-left-color: #ffffff;
+ border-width: 10px 0 10px 10px;
+}
+
+.popover.left .arrow:after {
+ right: -1px;
+ bottom: -11px;
+ border-left-color: rgba(0, 0, 0, 0.25);
+ border-width: 11px 0 11px 11px;
+}
+
+.thumbnails {
+ margin-left: -20px;
+ list-style: none;
+ *zoom: 1;
+}
+
+.thumbnails:before,
+.thumbnails:after {
+ display: table;
+ line-height: 0;
+ content: "";
+}
+
+.thumbnails:after {
+ clear: both;
+}
+
+.row-fluid .thumbnails {
+ margin-left: 0;
+}
+
+.thumbnails > li {
+ float: left;
+ margin-bottom: 20px;
+ margin-left: 20px;
+}
+
+.thumbnail {
+ display: block;
+ padding: 4px;
+ line-height: 20px;
+ border: 1px solid #ddd;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ -moz-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.055);
+ -webkit-transition: all 0.2s ease-in-out;
+ -moz-transition: all 0.2s ease-in-out;
+ -o-transition: all 0.2s ease-in-out;
+ transition: all 0.2s ease-in-out;
+}
+
+a.thumbnail:hover {
+ border-color: #0088cc;
+ -webkit-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+ -moz-box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+ box-shadow: 0 1px 4px rgba(0, 105, 214, 0.25);
+}
+
+.thumbnail > img {
+ display: block;
+ max-width: 100%;
+ margin-right: auto;
+ margin-left: auto;
+}
+
+.thumbnail .caption {
+ padding: 9px;
+ color: #555555;
+}
+
+.media,
+.media-body {
+ overflow: hidden;
+ *overflow: visible;
+ zoom: 1;
+}
+
+.media,
+.media .media {
+ margin-top: 15px;
+}
+
+.media:first-child {
+ margin-top: 0;
+}
+
+.media-object {
+ display: block;
+}
+
+.media-heading {
+ margin: 0 0 5px;
+}
+
+.media .pull-left {
+ margin-right: 10px;
+}
+
+.media .pull-right {
+ margin-left: 10px;
+}
+
+.media-list {
+ margin-left: 0;
+ list-style: none;
+}
+
+.label,
+.badge {
+ display: inline-block;
+ padding: 2px 4px;
+ font-size: 11.844px;
+ font-weight: bold;
+ line-height: 14px;
+ color: #ffffff;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ white-space: nowrap;
+ vertical-align: baseline;
+ background-color: #999999;
+}
+
+.label {
+ -webkit-border-radius: 3px;
+ -moz-border-radius: 3px;
+ border-radius: 3px;
+}
+
+.badge {
+ padding-right: 9px;
+ padding-left: 9px;
+ -webkit-border-radius: 9px;
+ -moz-border-radius: 9px;
+ border-radius: 9px;
+}
+
+a.label:hover,
+a.badge:hover {
+ color: #ffffff;
+ text-decoration: none;
+ cursor: pointer;
+}
+
+.label-important,
+.badge-important {
+ background-color: #b94a48;
+}
+
+.label-important[href],
+.badge-important[href] {
+ background-color: #953b39;
+}
+
+.label-warning,
+.badge-warning {
+ background-color: #f89406;
+}
+
+.label-warning[href],
+.badge-warning[href] {
+ background-color: #c67605;
+}
+
+.label-success,
+.badge-success {
+ background-color: #468847;
+}
+
+.label-success[href],
+.badge-success[href] {
+ background-color: #356635;
+}
+
+.label-info,
+.badge-info {
+ background-color: #3a87ad;
+}
+
+.label-info[href],
+.badge-info[href] {
+ background-color: #2d6987;
+}
+
+.label-inverse,
+.badge-inverse {
+ background-color: #333333;
+}
+
+.label-inverse[href],
+.badge-inverse[href] {
+ background-color: #1a1a1a;
+}
+
+.btn .label,
+.btn .badge {
+ position: relative;
+ top: -1px;
+}
+
+.btn-mini .label,
+.btn-mini .badge {
+ top: 0;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-moz-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-ms-keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+@-o-keyframes progress-bar-stripes {
+ from {
+ background-position: 0 0;
+ }
+ to {
+ background-position: 40px 0;
+ }
+}
+
+@keyframes progress-bar-stripes {
+ from {
+ background-position: 40px 0;
+ }
+ to {
+ background-position: 0 0;
+ }
+}
+
+.progress {
+ height: 20px;
+ margin-bottom: 20px;
+ overflow: hidden;
+ background-color: #f7f7f7;
+ background-image: -moz-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));
+ background-image: -webkit-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: -o-linear-gradient(top, #f5f5f5, #f9f9f9);
+ background-image: linear-gradient(to bottom, #f5f5f5, #f9f9f9);
+ background-repeat: repeat-x;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);
+ -webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ -moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+ box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
+}
+
+.progress .bar {
+ float: left;
+ width: 0;
+ height: 100%;
+ font-size: 12px;
+ color: #ffffff;
+ text-align: center;
+ text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
+ background-color: #0e90d2;
+ background-image: -moz-linear-gradient(top, #149bdf, #0480be);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));
+ background-image: -webkit-linear-gradient(top, #149bdf, #0480be);
+ background-image: -o-linear-gradient(top, #149bdf, #0480be);
+ background-image: linear-gradient(to bottom, #149bdf, #0480be);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);
+ -webkit-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -webkit-box-sizing: border-box;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+ -webkit-transition: width 0.6s ease;
+ -moz-transition: width 0.6s ease;
+ -o-transition: width 0.6s ease;
+ transition: width 0.6s ease;
+}
+
+.progress .bar + .bar {
+ -webkit-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ -moz-box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+ box-shadow: inset 1px 0 0 rgba(0, 0, 0, 0.15), inset 0 -1px 0 rgba(0, 0, 0, 0.15);
+}
+
+.progress-striped .bar {
+ background-color: #149bdf;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ -webkit-background-size: 40px 40px;
+ -moz-background-size: 40px 40px;
+ -o-background-size: 40px 40px;
+ background-size: 40px 40px;
+}
+
+.progress.active .bar {
+ -webkit-animation: progress-bar-stripes 2s linear infinite;
+ -moz-animation: progress-bar-stripes 2s linear infinite;
+ -ms-animation: progress-bar-stripes 2s linear infinite;
+ -o-animation: progress-bar-stripes 2s linear infinite;
+ animation: progress-bar-stripes 2s linear infinite;
+}
+
+.progress-danger .bar,
+.progress .bar-danger {
+ background-color: #dd514c;
+ background-image: -moz-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));
+ background-image: -webkit-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: -o-linear-gradient(top, #ee5f5b, #c43c35);
+ background-image: linear-gradient(to bottom, #ee5f5b, #c43c35);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);
+}
+
+.progress-danger.progress-striped .bar,
+.progress-striped .bar-danger {
+ background-color: #ee5f5b;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-success .bar,
+.progress .bar-success {
+ background-color: #5eb95e;
+ background-image: -moz-linear-gradient(top, #62c462, #57a957);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));
+ background-image: -webkit-linear-gradient(top, #62c462, #57a957);
+ background-image: -o-linear-gradient(top, #62c462, #57a957);
+ background-image: linear-gradient(to bottom, #62c462, #57a957);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);
+}
+
+.progress-success.progress-striped .bar,
+.progress-striped .bar-success {
+ background-color: #62c462;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-info .bar,
+.progress .bar-info {
+ background-color: #4bb1cf;
+ background-image: -moz-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));
+ background-image: -webkit-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: -o-linear-gradient(top, #5bc0de, #339bb9);
+ background-image: linear-gradient(to bottom, #5bc0de, #339bb9);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);
+}
+
+.progress-info.progress-striped .bar,
+.progress-striped .bar-info {
+ background-color: #5bc0de;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.progress-warning .bar,
+.progress .bar-warning {
+ background-color: #faa732;
+ background-image: -moz-linear-gradient(top, #fbb450, #f89406);
+ background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));
+ background-image: -webkit-linear-gradient(top, #fbb450, #f89406);
+ background-image: -o-linear-gradient(top, #fbb450, #f89406);
+ background-image: linear-gradient(to bottom, #fbb450, #f89406);
+ background-repeat: repeat-x;
+ filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);
+}
+
+.progress-warning.progress-striped .bar,
+.progress-striped .bar-warning {
+ background-color: #fbb450;
+ background-image: -webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));
+ background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: -o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+ background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+}
+
+.accordion {
+ margin-bottom: 20px;
+}
+
+.accordion-group {
+ margin-bottom: 2px;
+ border: 1px solid #e5e5e5;
+ -webkit-border-radius: 4px;
+ -moz-border-radius: 4px;
+ border-radius: 4px;
+}
+
+.accordion-heading {
+ border-bottom: 0;
+}
+
+.accordion-heading .accordion-toggle {
+ display: block;
+ padding: 8px 15px;
+}
+
+.accordion-toggle {
+ cursor: pointer;
+}
+
+.accordion-inner {
+ padding: 9px 15px;
+ border-top: 1px solid #e5e5e5;
+}
+
+.carousel {
+ position: relative;
+ margin-bottom: 20px;
+ line-height: 1;
+}
+
+.carousel-inner {
+ position: relative;
+ width: 100%;
+ overflow: hidden;
+}
+
+.carousel .item {
+ position: relative;
+ display: none;
+ -webkit-transition: 0.6s ease-in-out left;
+ -moz-transition: 0.6s ease-in-out left;
+ -o-transition: 0.6s ease-in-out left;
+ transition: 0.6s ease-in-out left;
+}
+
+.carousel .item > img {
+ display: block;
+ line-height: 1;
+}
+
+.carousel .active,
+.carousel .next,
+.carousel .prev {
+ display: block;
+}
+
+.carousel .active {
+ left: 0;
+}
+
+.carousel .next,
+.carousel .prev {
+ position: absolute;
+ top: 0;
+ width: 100%;
+}
+
+.carousel .next {
+ left: 100%;
+}
+
+.carousel .prev {
+ left: -100%;
+}
+
+.carousel .next.left,
+.carousel .prev.right {
+ left: 0;
+}
+
+.carousel .active.left {
+ left: -100%;
+}
+
+.carousel .active.right {
+ left: 100%;
+}
+
+.carousel-control {
+ position: absolute;
+ top: 40%;
+ left: 15px;
+ width: 40px;
+ height: 40px;
+ margin-top: -20px;
+ font-size: 60px;
+ font-weight: 100;
+ line-height: 30px;
+ color: #ffffff;
+ text-align: center;
+ background: #222222;
+ border: 3px solid #ffffff;
+ -webkit-border-radius: 23px;
+ -moz-border-radius: 23px;
+ border-radius: 23px;
+ opacity: 0.5;
+ filter: alpha(opacity=50);
+}
+
+.carousel-control.right {
+ right: 15px;
+ left: auto;
+}
+
+.carousel-control:hover {
+ color: #ffffff;
+ text-decoration: none;
+ opacity: 0.9;
+ filter: alpha(opacity=90);
+}
+
+.carousel-caption {
+ position: absolute;
+ right: 0;
+ bottom: 0;
+ left: 0;
+ padding: 15px;
+ background: #333333;
+ background: rgba(0, 0, 0, 0.75);
+}
+
+.carousel-caption h4,
+.carousel-caption p {
+ line-height: 20px;
+ color: #ffffff;
+}
+
+.carousel-caption h4 {
+ margin: 0 0 5px;
+}
+
+.carousel-caption p {
+ margin-bottom: 0;
+}
+
+.hero-unit {
+ padding: 60px;
+ margin-bottom: 30px;
+ font-size: 18px;
+ font-weight: 200;
+ line-height: 30px;
+ color: inherit;
+ background-color: #eeeeee;
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+}
+
+.hero-unit h1 {
+ margin-bottom: 0;
+ font-size: 60px;
+ line-height: 1;
+ letter-spacing: -1px;
+ color: inherit;
+}
+
+.hero-unit li {
+ line-height: 30px;
+}
+
+.pull-right {
+ float: right;
+}
+
+.pull-left {
+ float: left;
+}
+
+.hide {
+ display: none;
+}
+
+.show {
+ display: block;
+}
+
+.invisible {
+ visibility: hidden;
+}
+
+.affix {
+ position: fixed;
+}
diff --git a/app/assets/stylesheets/gemeinschaft-generic.css.scss b/app/assets/stylesheets/gemeinschaft-generic.css.scss
new file mode 100644
index 0000000..296b242
--- /dev/null
+++ b/app/assets/stylesheets/gemeinschaft-generic.css.scss
@@ -0,0 +1,13 @@
+// Place all the styles related to the Page controller here.
+// They will automatically be included in application.css.
+// You can use Sass (SCSS) here: http://sass-lang.com/
+
+body {
+ padding-top: 60px;
+ padding-bottom: 40px;
+}
+@media (max-width: 979px) {
+ body {
+ padding-top: 0px;
+ }
+}
diff --git a/app/assets/stylesheets/scaffolds.css.scss b/app/assets/stylesheets/scaffolds.css.scss
deleted file mode 100644
index 05188f0..0000000
--- a/app/assets/stylesheets/scaffolds.css.scss
+++ /dev/null
@@ -1,56 +0,0 @@
-body {
- background-color: #fff;
- color: #333;
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 13px;
- line-height: 18px; }
-
-p, ol, ul, td {
- font-family: verdana, arial, helvetica, sans-serif;
- font-size: 13px;
- line-height: 18px; }
-
-pre {
- background-color: #eee;
- padding: 10px;
- font-size: 11px; }
-
-a {
- color: #000;
- &:visited {
- color: #666; }
- &:hover {
- color: #fff;
- background-color: #000; } }
-
-div {
- &.field, &.actions {
- margin-bottom: 10px; } }
-
-#notice {
- color: green; }
-
-.field_with_errors {
- padding: 2px;
- background-color: red;
- display: table; }
-
-#error_explanation {
- width: 450px;
- border: 2px solid red;
- padding: 7px;
- padding-bottom: 0;
- margin-bottom: 20px;
- background-color: #f0f0f0;
- h2 {
- text-align: left;
- font-weight: bold;
- padding: 5px 5px 5px 15px;
- font-size: 12px;
- margin: -7px;
- margin-bottom: 0px;
- background-color: #c00;
- color: #fff; }
- ul li {
- font-size: 12px;
- list-style: square; } }
diff --git a/app/assets/stylesheets/api/rows.css.scss b/app/assets/stylesheets/trigger.css.scss
index 4fad3d5..682b362 100644
--- a/app/assets/stylesheets/api/rows.css.scss
+++ b/app/assets/stylesheets/trigger.css.scss
@@ -1,3 +1,3 @@
-// Place all the styles related to the api/rows controller here.
+// Place all the styles related to the trigger controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
diff --git a/app/assets/stylesheets/vendor/README b/app/assets/stylesheets/vendor/README
deleted file mode 100644
index 016b5fa..0000000
--- a/app/assets/stylesheets/vendor/README
+++ /dev/null
@@ -1 +0,0 @@
-Here you should place the files that are not part of your project, but you use them at some point. \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/boilerplate-1.0/README b/app/assets/stylesheets/vendor/boilerplate-1.0/README
deleted file mode 100644
index a5aa5b1..0000000
--- a/app/assets/stylesheets/vendor/boilerplate-1.0/README
+++ /dev/null
@@ -1,15 +0,0 @@
-HTML5 ✰ Boilerplate (ac92ae7a)
-
-style.css contains a reset, font normalization and some base styles.
-
-Credit is left where credit is due.
-Much inspiration was taken from these projects:
-- yui.yahooapis.com/2.8.1/build/base/base.css
-- camendesign.com/design/
-- praegnanz.de/weblog/htmlcssjs-kickstart
-
-Implementation to Compass as part of Survival Kit by Mario "Kuroir" Ricalde.
-
-Notes:
-
- Not implementing Non-semantic helper classes. Use Compass builts-in. \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/boilerplate-1.0/_reset.scss b/app/assets/stylesheets/vendor/boilerplate-1.0/_reset.scss
deleted file mode 100644
index efd1ac6..0000000
--- a/app/assets/stylesheets/vendor/boilerplate-1.0/_reset.scss
+++ /dev/null
@@ -1,37 +0,0 @@
-// html5doctor.com Reset Stylesheet (Eric Meyer's Reset Reloaded + HTML5 baseline)
-// v1.6.1 2010-09-17 | Authors: Eric Meyer & Richard Clark
-// html5doctor.com/html-5-reset-stylesheet/
-html, body, div, span, object, iframe,
-h1, h2, h3, h4, h5, h6, p, blockquote, pre,
-abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp,
-small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li,
-fieldset, form, label, legend,
-table, caption, tbody, tfoot, thead, tr, th, td,
-article, aside, canvas, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section, summary,
-time, mark, audio, video{
- margin: 0;
- padding: 0;
- border: 0;
- font-size: 100%;
- font: inherit;
- vertical-align: baseline;
-}
-
-article, aside, details, figcaption, figure,
-footer, header, hgroup, menu, nav, section {
- display: block;
-}
-
-blockquote, q { quotes: none; }
-
-blockquote:before, blockquote:after,
-q:before, q:after { content: ""; content: none; }
-
-del { text-decoration: line-through; }
-
-abbr[title], dfn[title] { border-bottom: 1px dotted; cursor: help; }
-
-table { border-collapse: collapse; border-spacing: 0; }
-
-input, select { vertical-align: middle; }
diff --git a/app/assets/stylesheets/vendor/boilerplate-1.0/_styles.scss b/app/assets/stylesheets/vendor/boilerplate-1.0/_styles.scss
deleted file mode 100644
index 3852329..0000000
--- a/app/assets/stylesheets/vendor/boilerplate-1.0/_styles.scss
+++ /dev/null
@@ -1,171 +0,0 @@
-// HTML5 ✰ Boilerplate
-//
-// style.css contains a reset, font normalization and some base styles.
-//
-// Credit is left where credit is due.
-// Much inspiration was taken from these projects:
-// - yui.yahooapis.com/2.8.1/build/base/base.css
-// - camendesign.com/design/
-// - praegnanz.de/weblog/htmlcssjs-kickstart
-//
-// Modified to fit Survival ✚ Kit
-
- html {
- @include sk-html;
- overflow-y: scroll;
- }
-
-
-// Sections (body, section, nav, article, aside, h1..6, header, footer, address)
-// ----------------------------------------
-
- body, select, input, textarea { color: $font-color; font-family: $base-font-family; }
-
- body { @include sk-body; font-size: $base-font-size; line-height: $base-line-height; }
-
-
-// Grouping Content (p, hr, pre, blockquote, ol, ul, li, dl, dt, dt, dd, figure, figcaption, div)
-// ----------------------------------------
-
- p { margin: 0 0 1em 0;}
- li { margin-bottom: (1em / 2);}
-
- hr { border: 0; border-top: 1px solid $hr-color; display: block; height: 1px; margin: 1em 0; padding: 0; }
-
- blockquote { color: #666; font-style: italic; margin: 1.5em; }
-
- // normalize monospace sizing
- // meyerweb.com/eric/thoughts/2010/02/12/fixed-monospace-sizing/
- // en.wikipedia.org/wiki/MediaWiki_talk:Common.css/Archive_11#Teletype_style_fix_for_Chrome
- pre {
- // www.pathf.com/blogs/2008/05/formatting-quoted-code-in-blog-posts-css21-white-space-pre-wrap/
- white-space: pre; white-space: pre-wrap; word-wrap: break-word;
- padding: 15px;
- }
-
- pre, code, kbd, samp { font-family: monospace, sans-serif; }
-
- // Lists
- ul, ol { margin:$list-margin; padding:$list-padding;}
-
- ol { list-style-type: decimal; }
-
- // Remove margin from navigation lists.
- nav ul,
- nav li { list-style:none; list-style-image: none; margin: 0; }
-
- // Lists
- dl { margin: 0 0 1.5em 0; }
-
- dl dt { font-weight: bold; }
-
- dd { margin-left: 1.5em;}
-
-
-// Text Level Semantics (a, em, strong, small, s, cite, q, dfn, abbr, time, code, var, samp, kbd, sub, i, b, u, mark, ruby, rt, rp, bdi, bdo, span, br, wbr)
-// ----------------------------------------
-
- // Accessible focus treatment: people.opera.com/patrickl/experiments/keyboard/test
- a {text-decoration:none;}
-
- a:hover, a:active { outline: none; text-decoration:underline;}
-
- a, a:active, a:visited { color: $link-color; }
-
- a:hover { color: $link-hover-color; }
-
- // Headers (h1, h2, etc) have no default font-size or margin; define those yourself
- h1, h2, h3, h4, h5, h6 { @include sk-header-tags; }
-
- // j.mp/webkit-tap-highlight-color
- a:link { -webkit-tap-highlight-color: #FF5E99; }
-
- small { font-size: 85%; }
-
- strong, b, th, dfn { font-weight: bold; }
-
- em, i { font-style:italic; }
-
- mark { background-color: #ff9; color: #000; font-style: italic; font-weight: bold; }
-
- abbr,
- acronym { border-bottom: 1px dotted #666; }
-
- address { font-style: italic; margin: 0 0 1.5em; }
-
- // Set sub, sup without affecting line-height: gist.github.com/413930
- sub, sup { font-size: 75%; line-height: 0; position: relative; }
-
- sup { top: -0.5em; }
-
- sub { bottom: -0.25em; }
-
-
-// Embedded Content (img)
-// ----------------------------------------
-
- // Bicubic resizing for non-native sized IMG:
- // code.flickr.com/blog/2008/11/12/on-ui-quality-the-little-things-client-side-image-resizing/
- .ie7 img { -ms-interpolation-mode: bicubic; }
-
-
-// Tabular Data (table, caption, colgroup, col, tbody, thead, tfoot, tr, td, th)
-// ----------------------------------------
-
- table { margin-bottom: 1.4em; width:100%; }
-
- th { font-weight: bold; }
-
- th,td,caption { padding: 4px 10px 4px 5px; text-align: left; }
-
-
-// Edits (ins, del)
-// ----------------------------------------
-
- ins { background-color: #ff9; color: #000; text-decoration: none; }
-
- del { color:#666; }
-
-
-// Forms
-// ----------------------------------------
-
- select, input, textarea, button { font: 99% $base-font-family; outline:none;}
-
- td { vertical-align: top; }
-
- textarea { overflow: auto; }
-
- // Align checkboxes, radios, text inputs with their label by: Thierry Koblentz tjkdesign.com/ez-css/css/base.css
- input[type="radio"] { vertical-align: text-bottom; }
-
- input[type="checkbox"] { vertical-align: bottom; }
-
- // Hand cursor on clickable input elements
-
- label, input[type="button"], input[type="submit"], input[type="image"], button { cursor: pointer; }
-
- // Webkit browsers add a 2px margin outside the chrome of form elements
- button, input, select, textarea { margin: 0; }
-
-
- // required:valid and required:invalid moved to form.scss
-
- // Make buttons play nice in IE:
- // www.viget.com/inspire/styling-the-button-element-in-internet-explorer/
- button { overflow: visible; width: auto; }
-
- @if in-compatibility-mode() {
- .ie7 input[type="checkbox"] { vertical-align: baseline; }
-
- .ie6 input { vertical-align: text-bottom; }
-
- .ie6 legend, .ie7 legend { margin-left: -7px; }
- }
-
-
-// Etc.
-// ----------------------------------------
-
- ::-moz-selection{ background: $selected-background-color; color:$selected-font-color; text-shadow: none; }
- ::selection { background:$selected-background-color; color:$selected-font-color; text-shadow: none; }
diff --git a/app/assets/stylesheets/vendor/boilerplate-2.0/README b/app/assets/stylesheets/vendor/boilerplate-2.0/README
deleted file mode 100644
index c9cd066..0000000
--- a/app/assets/stylesheets/vendor/boilerplate-2.0/README
+++ /dev/null
@@ -1,16 +0,0 @@
-HTML5 ✰ Boilerplate 2.0 (7467f9c0417a0c1f9863e2d000aad73f34836ef2)
-
-style.css contains a reset, font normalization and some base styles.
-
-Credit is left where credit is due.
-Much inspiration was taken from these projects:
-- yui.yahooapis.com/2.8.1/build/base/base.css
-- camendesign.com/design/
-- praegnanz.de/weblog/htmlcssjs-kickstart
-
-Implementation to Compass as part of Survival Kit by Mario "Kuroir" Ricalde.
-
-Notes:
-
- - Not implementing Non-semantic helper classes. Use Compass builts-in.
- - 1.0 and 2.0 are very similar. With 2.0 you save a couple of bytes.. maybe not worth the change? \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/boilerplate-2.0/_styles.scss b/app/assets/stylesheets/vendor/boilerplate-2.0/_styles.scss
deleted file mode 100644
index 6268a35..0000000
--- a/app/assets/stylesheets/vendor/boilerplate-2.0/_styles.scss
+++ /dev/null
@@ -1,209 +0,0 @@
-//
-// HTML5 ✰ Boilerplate
-//
-// What follows is the result of much research on cross-browser styling.
-// Credit left inline and big thanks to Nicolas Gallagher, Jonathan Neal,
-// Kroc Camen, and the H5BP dev community and team.
-//
-// Detailed information about this CSS: h5bp.com/css
-//
-// ==|== normalize ==========================================================
-//
-
-
-// ==========================================================================
-// HTML5 display definitions
-// ==========================================================================
-
-article, aside, details, figcaption, figure, footer, header, hgroup, nav, section { display: block; }
-audio, canvas, video { display: inline-block; *display: inline; *zoom: 1; }
-audio:not([controls]) { display: none; }
-[hidden] { display: none; }
-
-// ==========================================================================
-// Base
-// ==========================================================================
-
-//
-// 1. Correct text resizing oddly in IE6/7 when body font-size is set using em units
-// 2. Force vertical scrollbar in non-IE
-// 3. Prevent iOS text size adjust on device orientation change, without disabling user zoom: h5bp.com/g
-//
-
-html { font-size: 100%; overflow-y: scroll; -webkit-text-size-adjust: 100%; -ms-text-size-adjust: 100%; }
-
-body { margin: 0; font-size: $base-font-size; line-height: $base-line-height; }
-
-body, button, input, select, textarea { font-family: $base-font-family; color: $font-color; }
-
-//
-// Remove text-shadow in selection highlight: h5bp.com/i
-// These selection declarations have to be separate
-// Also: hot pink! (or customize the background color to match your design)
-//
-
-::-moz-selection { background: $selected-background-color; color: $selected-font-color; text-shadow: none; }
-::selection { background: $selected-background-color; color: $selected-font-color; text-shadow: none; }
-
-
-// ==========================================================================
-// Links
-// ==========================================================================
-
-a { color: $link-color; }
-a:visited { color: $link-visited-color; }
-a:hover { color: $link-hover-color; }
-a:focus { outline: thin dotted; }
-
-/* Improve readability when focused and hovered in all browsers: h5bp.com/h */
-a:hover, a:active { outline: 0; }
-
-
-// ==========================================================================
-// Typography
-// ==========================================================================
-
-abbr[title] { border-bottom: 1px dotted; }
-
-b, strong { font-weight: bold; }
-
-i, em { font-style:italic;}
-
-blockquote { margin: 1em 40px; }
-
-dfn { font-style: italic; }
-
-hr { display: block; height: 1px; border: 0; border-top: 1px solid $hr-color; margin: 1em 0; padding: 0; }
-
-ins { background: #ff9; color: #000; text-decoration: none; }
-
-mark { background: #ff0; color: #000; font-style: italic; font-weight: bold; }
-
-// Redeclare monospace font family: h5bp.com/j
-pre, code, kbd, samp { font-family: monospace, monospace; _font-family: 'courier new', monospace; font-size: 1em; }
-
-// Improve readability of pre-formatted text in all browsers
-pre { white-space: pre; white-space: pre-wrap; word-wrap: break-word; }
-
-q { quotes: none; }
-q:before, q:after { content: ""; content: none; }
-
-small { font-size: 85%; }
-
-// Position subscript and superscript content without affecting line-height: h5bp.com/k
-sub, sup { font-size: 75%; line-height: 0; position: relative; vertical-align: baseline; }
-sup { top: -0.5em; }
-sub { bottom: -0.25em; }
-
-
-// ==========================================================================
-// Lists
-// ==========================================================================
-dl {margin:$list-margin;}
-ul, ol { margin: $list-margin; padding: $list-padding; }
-dd { margin: 0 0 0 40px; }
-nav ul, nav ol { list-style: none; list-style-image: none; margin: 0; padding: 0; }
-
-
-// ==========================================================================
-// Embedded content
-// ==========================================================================
-
-//
-// 1. Improve image quality when scaled in IE7: h5bp.com/d
-// 2. Remove the gap between images and borders on image containers: h5bp.com/e
-//
-
-img { border: 0; -ms-interpolation-mode: bicubic; vertical-align: middle; }
-
-//
-// Correct overflow not hidden in IE9
-//
-
-svg:not(:root) { overflow: hidden; }
-
-
-// ==========================================================================
-// Figures
-// ==========================================================================
-
-figure { margin: 0; }
-
-
-// ==========================================================================
-// Forms
-// ==========================================================================
-
-form { margin: 0; }
-fieldset { border: 0; margin: 0; padding: 0; }
-
-// Indicate that 'label' will shift focus to the associated form element
-label { cursor: pointer; }
-
-//
-// 1. Correct color not inheriting in IE6/7/8/9
-// 2. Correct alignment displayed oddly in IE6/7
-//
-
-legend { border: 0; *margin-left: -7px; padding: 0; }
-
-//
-// 1. Correct font-size not inheriting in all browsers
-// 2. Remove margins in FF3/4 S5 Chrome
-// 3. Define consistent vertical alignment display in all browsers
-//
-
-button, input, select, textarea { font-size: 100%; margin: 0; vertical-align: baseline; *vertical-align: middle; }
-
-//
-// 1. Define line-height as normal to match FF3/4 (set using !important in the UA stylesheet)
-// 2. Correct inner spacing displayed oddly in IE6/7
-//
-
-button, input { line-height: normal; *overflow: visible; }
-
-//
-// Reintroduce inner spacing in 'table' to avoid overlap and whitespace issues in IE6/7
-//
-
-table button, table input { *overflow: auto; }
-
-//
-// 1. Display hand cursor for clickable form elements
-// 2. Allow styling of clickable form elements in iOS
-//
-
-button, input[type="button"], input[type="reset"], input[type="submit"] { cursor: pointer; -webkit-appearance: button; }
-
-//
-// Consistent box sizing and appearance
-//
-
-input[type="checkbox"], input[type="radio"] { box-sizing: border-box; }
-input[type="search"] { -webkit-appearance: textfield; -moz-box-sizing: content-box; -webkit-box-sizing: content-box; box-sizing: content-box; }
-input[type="search"]::-webkit-search-decoration { -webkit-appearance: none; }
-
-//
-// Remove inner padding and border in FF3/4: h5bp.com/l
-//
-
-button::-moz-focus-inner, input::-moz-focus-inner { border: 0; padding: 0; }
-
-//
-// 1. Remove default vertical scrollbar in IE6/7/8/9
-// 2. Allow only vertical resizing
-//
-
-textarea { overflow: auto; vertical-align: top; resize: vertical; }
-
-// Colors for form validity
-input:valid, textarea:valid { }
-input:invalid, textarea:invalid { background-color: #f0dddd; }
-
-
-// ==========================================================================
-// Tables
-// ==========================================================================
-
-table { border-collapse: collapse; border-spacing: 0; }
-td { vertical-align: top; } \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/easy-slider/_numeric.scss b/app/assets/stylesheets/vendor/easy-slider/_numeric.scss
deleted file mode 100644
index db61e78..0000000
--- a/app/assets/stylesheets/vendor/easy-slider/_numeric.scss
+++ /dev/null
@@ -1,44 +0,0 @@
-//
-// @TODO: Add docs to easy-slider-numeric!
-//
-@mixin easy-slider-numeric($width, $height, $selector:'#slider') {
- #{$selector} {
- & ul, & li {
- margin:0;
- padding:0;
- list-style:none;
- }
- & li {
- width:$width;
- height:$height;
- overflow:hidden;
- }
- }
- @include _numeric-controls();
-}
-
-// You can override this function to alter the appearance of the numeric controls.
-@mixin _numeric-controls() {
- #controls{
- margin:10px 0;
- line-height:28px;
- list-style:none;
- text-align:right;
- li {
- @include inline-block;
- margin:0 0 0 10px;
- }
- .current a {
- background:#FFFFFF;
- color:#C80111;
- @include box-shadow(0px 0px 3px #B2B2B2);
- padding:6px 11px; // Simulate "hover"
- }
- a {
- padding:5px 10px;
- background:#F5F5F5;
- border: 1px solid #AEAEAE;
- color: #7F7F7F;
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/facebox/_facebox.scss b/app/assets/stylesheets/vendor/facebox/_facebox.scss
deleted file mode 100644
index 53e612d..0000000
--- a/app/assets/stylesheets/vendor/facebox/_facebox.scss
+++ /dev/null
@@ -1,85 +0,0 @@
-$facebox-overlay: #000 !default;
-#facebox {
- left: 0;
- position: fixed;
- text-align: left;
- top: 0;
- z-index: 100;
-}
-
-
-#facebox .popup{
- border:9px solid rgba(0, 157, 214, 0.8);
- border-radius:5px;
- -moz-border-radius:5px;
- -webkit-border-radius:5px;
- box-shadow:0 0 18px rgba(0,0,0,0.4);
- -moz-box-shadow:0 0 18px rgba(0,0,0,0.4);
- -webkit-box-shadow:0 0 18px rgba(0,0,0,0.4);
- position:relative;
-}
-
-#facebox .content {
- background: #fff;
- border-radius:4px;
- -moz-border-radius:4px;
- -webkit-border-radius:4px;
- display:table;
- min-width: 370px;
- padding: 10px;
-}
-
-#facebox .content > p:first-child{
- margin-top:0;
-}
-#facebox .content > p:last-child{
- margin-bottom:0;
-}
-
-#facebox .close{
- padding:2px;
- position:absolute;
- right:5px;
- top:5px;
- z-index:101;
-}
-#facebox .close img{
- opacity:0.3;
-}
-#facebox .close:hover img{
- opacity:1.0;
-}
-
-#facebox .loading {
- text-align: center;
-}
-
-#facebox .image {
- text-align: center;
-}
-
-#facebox img {
- border: 0;
- margin: 0;
-}
-
-#facebox_overlay {
- height:100%;
- left: 0px;
- position: fixed;
- top: 0px;
- width:100%;
-}
-
-.facebox_hide {
- z-index:-100;
-}
-
-.facebox_overlayBG {
- background-color: $facebox-overlay;
- z-index: 99;
-}
-
-#facebox h1{
- margin: 0 0 10px 0;
-}
diff --git a/app/assets/stylesheets/vendor/fancy-box/README b/app/assets/stylesheets/vendor/fancy-box/README
deleted file mode 100644
index 70212dd..0000000
--- a/app/assets/stylesheets/vendor/fancy-box/README
+++ /dev/null
@@ -1,4 +0,0 @@
-Fancybox 1.3.4 (2010/11/11)
-Licensed under both MIT and GPL licenses
-
-http://fancybox.net/ \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/fancy-box/_fancy-box.scss b/app/assets/stylesheets/vendor/fancy-box/_fancy-box.scss
deleted file mode 100755
index 7ec2644..0000000
--- a/app/assets/stylesheets/vendor/fancy-box/_fancy-box.scss
+++ /dev/null
@@ -1,336 +0,0 @@
-//
-// FancyBox - jQuery Plugin
-// Simple and fancy lightbox alternative
-//
-// Examples and documentation at: http://fancybox.net
-//
-// Copyright (c) 2008 - 2010 Janis Skarnelis
-// That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
-//
-// Version: 1.3.4 (11/11/2010)
-// Requires: jQuery v1.3+
-//
-// Dual licensed under the MIT and GPL licenses:
-// http://www.opensource.org/licenses/mit-license.php
-// http://www.gnu.org/licenses/gpl.html
-//
-
-#fancybox-loading {
- position: fixed;
- top: 50%;
- left: 50%;
- width: 40px;
- height: 40px;
- margin-top: -20px;
- margin-left: -20px;
- cursor: pointer;
- overflow: hidden;
- z-index: 1104;
- display: none;
-}
-
-#fancybox-loading div {
- position: absolute;
- top: 0;
- left: 0;
- width: 40px;
- height: 480px;
- background-image: image-url('vendor/fancy-box/fancybox.png');
-}
-
-#fancybox-overlay {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- z-index: 1100;
- display: none;
-}
-
-#fancybox-tmp {
- padding: 0;
- margin: 0;
- border: 0;
- overflow: auto;
- display: none;
-}
-
-#fancybox-wrap {
- position: absolute;
- top: 0;
- left: 0;
- padding: 20px;
- z-index: 1101;
- outline: none;
- display: none;
-}
-
-#fancybox-outer {
- position: relative;
- width: 100%;
- height: 100%;
- background: #fff;
-}
-
-#fancybox-content {
- width: 0;
- height: 0;
- padding: 0;
- outline: none;
- position: relative;
- overflow: hidden;
- z-index: 1102;
- border: 0px solid #fff;
-}
-
-#fancybox-hide-sel-frame {
- position: absolute;
- top: 0;
- left: 0;
- width: 100%;
- height: 100%;
- background: transparent;
- z-index: 1101;
-}
-
-#fancybox-close {
- position: absolute;
- top: -15px;
- right: -15px;
- width: 30px;
- height: 30px;
- background: transparent image-url('vendor/fancy-box/fancybox.png') -40px 0px;
- cursor: pointer;
- z-index: 1103;
- display: none;
-}
-
-#fancybox-error {
- color: #444;
- font: normal 12px/20px Arial;
- padding: 14px;
- margin: 0;
-}
-
-#fancybox-img {
- width: 100%;
- height: 100%;
- padding: 0;
- margin: 0;
- border: none;
- outline: none;
- line-height: 0;
- vertical-align: top;
-}
-
-#fancybox-frame {
- width: 100%;
- height: 100%;
- border: none;
- display: block;
-}
-
-#fancybox-left, #fancybox-right {
- position: absolute;
- bottom: 0px;
- height: 100%;
- width: 35%;
- cursor: pointer;
- outline: none;
- background: transparent image-url('vendor/fancy-box/blank.gif');
- z-index: 1102;
- display: none;
-}
-
-#fancybox-left {
- left: 0px;
-}
-
-#fancybox-right {
- right: 0px;
-}
-
-#fancybox-left-ico, #fancybox-right-ico {
- position: absolute;
- top: 50%;
- left: -9999px;
- width: 30px;
- height: 30px;
- margin-top: -15px;
- cursor: pointer;
- z-index: 1102;
- display: block;
-}
-
-#fancybox-left-ico {
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -30px;
-}
-
-#fancybox-right-ico {
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -60px;
-}
-
-#fancybox-left:hover, #fancybox-right:hover {
- visibility: visible; /* IE6 */
-}
-
-#fancybox-left:hover span {
- left: 20px;
-}
-
-#fancybox-right:hover span {
- left: auto;
- right: 20px;
-}
-
-.fancybox-bg {
- position: absolute;
- padding: 0;
- margin: 0;
- border: 0;
- width: 20px;
- height: 20px;
- z-index: 1001;
-}
-
-#fancybox-bg-n {
- top: -20px;
- left: 0;
- width: 100%;
- background-image: image-url('vendor/fancy-box/fancybox-x.png');
-}
-
-#fancybox-bg-ne {
- top: -20px;
- right: -20px;
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -162px;
-}
-
-#fancybox-bg-e {
- top: 0;
- right: -20px;
- height: 100%;
- background-image: image-url('vendor/fancy-box/fancybox-y.png');
- background-position: -20px 0px;
-}
-
-#fancybox-bg-se {
- bottom: -20px;
- right: -20px;
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -182px;
-}
-
-#fancybox-bg-s {
- bottom: -20px;
- left: 0;
- width: 100%;
- background-image: image-url('vendor/fancy-box/fancybox-x.png');
- background-position: 0px -20px;
-}
-
-#fancybox-bg-sw {
- bottom: -20px;
- left: -20px;
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -142px;
-}
-
-#fancybox-bg-w {
- top: 0;
- left: -20px;
- height: 100%;
- background-image: image-url('vendor/fancy-box/fancybox-y.png');
-}
-
-#fancybox-bg-nw {
- top: -20px;
- left: -20px;
- background-image: image-url('vendor/fancy-box/fancybox.png');
- background-position: -40px -122px;
-}
-
-#fancybox-title {
- font-family: Helvetica;
- font-size: 12px;
- z-index: 1102;
-}
-
-.fancybox-title-inside {
- padding-bottom: 10px;
- text-align: center;
- color: #333;
- background: #fff;
- position: relative;
-}
-
-.fancybox-title-outside {
- padding-top: 10px;
- color: #fff;
-}
-
-.fancybox-title-over {
- position: absolute;
- bottom: 0;
- left: 0;
- color: #FFF;
- text-align: left;
-}
-
-#fancybox-title-over {
- padding: 10px;
- background-image: image-url('vendor/fancy-box/fancy_title_over.png');
- display: block;
-}
-
-.fancybox-title-float {
- position: absolute;
- left: 0;
- bottom: -20px;
- height: 32px;
-}
-
-#fancybox-title-float-wrap {
- border: none;
- border-collapse: collapse;
- width: auto;
-}
-
-#fancybox-title-float-wrap td {
- border: none;
- white-space: nowrap;
-}
-
-#fancybox-title-float-left {
- padding: 0 0 0 15px;
- background: image-url('vendor/fancy-box/fancybox.png') -40px -90px no-repeat;
-}
-
-#fancybox-title-float-main {
- color: #FFF;
- line-height: 29px;
- font-weight: bold;
- padding: 0 0 3px 0;
- background: image-url('vendor/fancy-box/fancybox-x.png') 0px -40px;
-}
-
-#fancybox-title-float-right {
- padding: 0 0 0 15px;
- background: image-url('vendor/fancy-box/fancybox.png') -55px -90px no-repeat;
-}
-
-/* IE6, IE7, IE8 */
-
-.fancybox-ie .fancybox-bg { background: transparent !important; }
-
-.fancybox-ie #fancybox-bg-n { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_n.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-ne { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_ne.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-e { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_e.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-se { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_se.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-s { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_s.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-sw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_sw.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-w { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_w.png', sizingMethod='scale'); }
-.fancybox-ie #fancybox-bg-nw { filter: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='fancybox/fancy_shadow_nw.png', sizingMethod='scale'); } \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/fancy-buttons/README b/app/assets/stylesheets/vendor/fancy-buttons/README
deleted file mode 100644
index 9ee6cc3..0000000
--- a/app/assets/stylesheets/vendor/fancy-buttons/README
+++ /dev/null
@@ -1,3 +0,0 @@
- Fancy Buttons by imathis
- https://github.com/imathis/fancy-buttons
- License: MIT \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/fancy-buttons/_fancy-buttons.scss b/app/assets/stylesheets/vendor/fancy-buttons/_fancy-buttons.scss
deleted file mode 100644
index 2e85caf..0000000
--- a/app/assets/stylesheets/vendor/fancy-buttons/_fancy-buttons.scss
+++ /dev/null
@@ -1,195 +0,0 @@
-@import "compass/css3/gradient";
-@import "compass/css3/border-radius";
-@import "compass/css3/opacity";
-@import "compass/css3/text-shadow";
-@import "compass/css3/box-shadow";
-@import "compass/css3/background-clip";
-@import "fancy-gradient";
-
-$fb-gradient-style: glossy !default;
-$fb-invert-on-click: 1 !default;
-$fb-font-size: 18px !default;
-$fb-color: #444444 !default;
-$fb-font-weight: bold !default;
-$fb-border-width: 1px !default;
-$fb-radius: 6px !default;
-$fb-light-text: white !default;
-$fb-dark-text: #222222 !default;
-$fb-gradient: 1 !default;
-$fb-image-path: image-url("vendor/fancy-buttons/button_bg.png") !default;
-$fb-allow-disabled: false !default;
-$fb-line-height: 1.2em !default;
-
-// Make a fancy button.
-@mixin fancy-button($color: $fb-color, $font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width) {
- @include fancy-button-structure($font-size, $radius, $border-width);
- @include fancy-button-colors($color);
-}
-
-// Style the button's colors, picking the most appropriate color set for the base color.
-@mixin fancy-button-colors($color: $fb-color, $hover: 0, $active: 0, $fb-allow-disabled: $fb-allow-disabled) {
- @include fb-color($color, "default");
- &:hover, &:focus {
- @if $hover == 0 {
- @include fb-color(darken($color, 3), "hover", $color); }
- @else {
- @include fb-color($hover, "hover"); } }
- &:active {
- @if $active == 0 {
- @include fb-color(darken($color, 6), "active", $color);
- @include box-shadow(darken($color, 15) 0 0.08em 0.2em 1px inset); }
- @else {
- @include fb-color($active, "active");
- @include box-shadow(darken($active, 9) 0 0.08em 0.1em 1px inset); } }
- @include box-shadow(rgba(white, lightness($color) / 100) 0 0 0.1em 1px inset);
- @include background-clip(padding-box);
- @if $fb-allow-disabled {
- &.disabled, &[disabled] {
- @include disable-fancy-button($color);
- }
- }
-}
-
-@mixin fancy-button-allow-disable($color: $fb-color, $font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width) {
- $fb-disable-allowed: $fb-allow-disabled;
- $fb-allow-disabled: true;
- @include fancy-button-structure($font-size, $radius, $border-width);
- @include fancy-button-colors-matte($color);
- $fb-allow-disabled: $fb-disable-allowed;
-}
-
-@mixin fancy-button-matte($color: $fb-color, $font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width) {
- @include fancy-button-structure($font-size, $radius, $border-width);
- @include fancy-button-colors-matte($color);
-}
-
-@mixin fancy-button-custom($color: $fb-color, $font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width) {
- @include fancy-button-structure($font-size, $radius, $border-width);
- @include fancy-button-colors-custom($color, $font-size, $radius, $border-width);
-}
-
-@mixin fancy-button-colors-matte($color: $fb-color, $hover: 0, $active: 0) {
- $fb-current-style: $fb-gradient-style;
- $fb-gradient-style: matte;
- @include fancy-button-colors($color, $hover, $active);
- $fb-gradient-style: $fb-current-style;
-}
-
-@mixin fancy-button-colors-custom($color: $fb-color, $hover: 0, $active: 0) {
- $fb-current-style: $fb-gradient-style;
- $fb-gradient-style: custom;
- @include fancy-button-colors($color, $hover, $active);
- $fb-gradient-style: $fb-current-style;
-}
-
-// Default state color settings
-@mixin fb-color($color, $state, $lumins: $color) {
- $gradient-top: lighten($color, 15);
- $gradient-bottom: darken($color, 6);
- $border-color: darken($color, 8);
- @if $fb-invert-on-click != 0 {
- $border-color: darken($color, 15); }
- @if saturation($color) > 0 {
- $color: saturate($color, 40); }
- @else if lightness($lumins) >= lightness(#aaaaaa) {
- $color: lighten($color, 20); }
- @include fb-state-colors($color, $gradient-top, $gradient-bottom, $border-color, $state, $lumins);
-}
-
-// Apply the button colors specified for the button state into which it is mixed.
-@mixin fb-state-colors($color, $gradient-top, $gradient-bottom, $border, $state, $lumins: $color) {
- background-color: $color;
- @if $fb-gradient != 0 {
- @if $fb-gradient-style == "glossy" {
- @if $state == "active" {
- @include fancy-gradient-active($gradient-top, $gradient-bottom); }
- @else {
- @include fancy-gradient($gradient-top, $gradient-bottom); } }
- @else if $fb-gradient-style == "matte" {
- @if $state == "active" {
- @include fancy-matte-gradient-active($gradient-top, $gradient-bottom); }
- @else {
- @include fancy-matte-gradient($gradient-top, $gradient-bottom); } }
- @else if $fb-gradient-style == "custom" {
- @if $state == "active" {
- @include custom-fancy-gradient-active($gradient-top, $gradient-bottom); }
- @else {
- @include custom-fancy-gradient($gradient-top, $gradient-bottom); } } }
- border: {
- color: $border; };
- $text-shadow-settings: unquote("0px 1px 1px");
- @if $fb-invert-on-click != 0 and $state == "active" {
- $text-shadow-settings: unquote("0px -1px -1px"); }
- @if lightness($lumins) < lightness(#aaaaaa) {
- text-shadow: darken($color, 25) $text-shadow-settings;
- &, &:visited {
- color: $fb-light-text; } }
- @else {
- text-shadow: lighten($color, 15) $text-shadow-settings;
- &, &:visited {
- color: $fb-dark-text; } }
-}
-
-@mixin fancy-button-text-colors($color, $hover: $color, $active: $color, $fb-allow-disabled: $fb-allow-disabled) {
- &, &:visited {
- color: $color; }
- &:hover, &:focus {
- color: $hover; }
- &:active {
- color: $active; }
- @if $fb-allow-disabled {
- &.disabled, &[disabled] {
- color: $color; } }
-}
-
-// Layout the button's box
-@mixin fancy-button-structure($font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width, $line-height: $fb-line-height) {
- @extend .fancy-button-reset-base-class;
- @include fancy-button-size($font-size, $radius, $border-width, $line-height);
-}
-
-@mixin fancy-button-size($font-size: $fb-font-size, $radius: $fb-radius, $border-width: $fb-border-width, $line-height: $fb-line-height) {
- // better padding for smaller buttons
- $v-padding: 0.3em;
- $h-padding: 1em;
- @if $radius > 0 {
- @include border-radius($radius); }
- font-size: $font-size;
- line-height: $line-height;
- @include fancy-button-padding($v-padding, $h-padding, $border-width);
-}
-
-@mixin fancy-button-padding($v-padding, $h-padding, $border-width: $fb-border-width) {
- padding: $v-padding $h-padding;
- border-width: $border-width;
-}
-
-// Reset the button's important properties to make sure they behave correctly
-@mixin fb-reset($font-weight: $fb-font-weight) {
- font-family: "Lucida Grande", Lucida, Arial, sans-serif;
- background: #{$fb-image-path} repeat-x bottom left;
- margin: 0;
- width: auto;
- overflow: visible;
- display: inline-block;
- cursor: pointer;
- text-decoration: none;
- border-style: solid;
- font-weight: $font-weight;
- &::-moz-focus-inner {
- border: none;
- padding: 0; }
- &:focus {
- outline: none; }
-}
-
-@mixin disable-fancy-button($color: $fb-color, $opacity: 0.7) {
- @include fb-color($color, "default");
- @include opacity($opacity);
- @include box-shadow(none);
- cursor: default !important;
-}
-
-.fancy-button-reset-base-class {
- @include fb-reset;
-}
diff --git a/app/assets/stylesheets/vendor/fancy-buttons/_fancy-gradient.scss b/app/assets/stylesheets/vendor/fancy-buttons/_fancy-gradient.scss
deleted file mode 100644
index da0baa9..0000000
--- a/app/assets/stylesheets/vendor/fancy-buttons/_fancy-gradient.scss
+++ /dev/null
@@ -1,28 +0,0 @@
-@mixin fancy-gradient($color1, $color2) {
- $top_shine: lighten($color1, 18);
- $bottom_glow: lighten($color2, 10);
- $top_middle: $color1;
- $middle: lighten($color2, 3);
- $bottom_middle: $color2;
- @include background-image(linear-gradient($top_shine, $top_middle 10%, $middle 50%, $bottom_middle 50%, $bottom_glow)); }
-
-@mixin fancy-gradient-active($color1, $color2) {
- $top: lighten($color2, 6);
- $bottom: lighten($color2, 14);
- $top_middle: lighten($color2, 8);
- $middle: lighten($color2, 4);
- $bottom_middle: lighten($color2, 1);
- @include background-image(linear-gradient($top, $top_middle 30%, $middle 50%, $bottom_middle 50%, $bottom)); }
-
-@mixin fancy-matte-gradient($color1, $color2) {
- @include background-image(linear-gradient($color1, $color2)); }
-
-@mixin fancy-matte-gradient-active($color1, $color2) {
- $top: lighten($color2, 5);
- $bottom: lighten($color2, 15);
- $middle: lighten($color2, 8);
- @include background-image(linear-gradient($top, $middle 40%, $middle 85%, $bottom)); }
-
-/* incase an inverted custom gradient isn't specified */
-@mixin custom-fancy-gradient-active($color1, $color2) {
- @include custom-fancy-gradient($color1, $color2); }
diff --git a/app/assets/stylesheets/vendor/survival-kit/_blog.scss b/app/assets/stylesheets/vendor/survival-kit/_blog.scss
deleted file mode 100644
index 5bec255..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_blog.scss
+++ /dev/null
@@ -1,99 +0,0 @@
-// Survival ✚ Kit
-
-// News Item
-// ----------------------------------------
-// <div class="blog-item">
-// <h6 class="date">14 de Julio 2010</h6>
-// <h3><a href="#">Lorem My Ipsum</a></h3>
-// <img src="image.jpg" width="194" height="146" alt="Blog Thumb"/>
-// <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras nec ipsum magna. Duis porttitor, felis quis eleifend vehicula, mauris mi varius nibh, sit amet iaculis magna magna vitae justo...</p>
-// <p class="read-more"><a href="#">Nota Completa</a></p>
-// </div>
-@mixin news-item($date:#383838, $header:#1491EE) {
- @include clearfix;
- .date {
- color:$date;
- font:{
- size:11px;
- weight:normal;
- };
- }
- img {
- float:left;
- padding: 4px 14px 50px 0;
- }
- p {
- color:$link-color;
- }
- h3 {
- margin-bottom:8px;
- a{
- color:$header;
- font-size:15px;
- font-weight:bold;
- text-decoration:none;
- }
- }
-}
-
-
-// Pagination Styling
-// ----------------------------------------
-// <div class="pagination">
-// <span class="previous_page disabled">← Previous</span>
-// <em>1</em>
-// <a rel="next" href="/?page=2">2</a>
-// <a href="/?page=3">3</a>
-// <a href="/?page=4">4</a>
-// <a class="next_page" rel="next" href="/?page=2">Next →</a>
-// </div>
-
-// Notes for Later
-//$active-state: (border (1px solid red), height 300px, ..[infinite]);
-// Would Output:
-// border: 1px solid red; heigh: 300px;
-
-// Normal, hover, active, disabled
-//$pagination-font-weights: normal bold normal;
-//$pagination-font-colors: #7F7F7F yellow #FFFFFF #4C7DB5;
-//$pagination-borders:none (1px solid #4C7DB5) (none) (1px solid #D0D0D0);
-//$pagination-backgrounds: #F5F5F5 #FFFFFF none none;
-// color, background, border, weight
-//@include pagination(#7F7F7F yellow #FFFFFF #4C7DB5, #F5F5F5 #FFFFFF none none, none (1px solid #4C7DB5) (none) (1px solid #D0D0D0), );
-
-@mixin pagination() {
- text-align:center;
- * {
- @include border-radius(4px);
- }
- .current {
- font-weight:bold;
- color:#0090BC;
- font-size:14px;
- padding: 3px 8px;
- margin-right:2px;
- }
- .disabled {
- color:#518CBC;
- border:1px solid #518CBC;
- }
- a {
- padding: 3px 8px;
- @include gradient(#80DFFF, #3BBBE7);
- @include box-shadow(0 2px 0px #EBEBEB);
- text-decoration:none;
- color: #FFF;
- font-weight: bold;
- border:1px solid #4DC6EF;
- &:active {
- @include box-shadow(0px 1px #96C5FA, inset 0px 1px #5D96CC);
- background:#F6FAFC !important;
- }
- &:hover {
- background:#D0F0FC;
- border:1px solid #4DC6EF;
- color:$link-hover-color;
- @include box-shadow(none);
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_effects.scss b/app/assets/stylesheets/vendor/survival-kit/_effects.scss
deleted file mode 100644
index 488a83a..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_effects.scss
+++ /dev/null
@@ -1,97 +0,0 @@
-// Survival ✚ Kit
-
-// Add a Bendy shadow to a squar element.
-// @author Chris Eppstein
-@mixin bendy-shadow($width, $angle: 5deg, $color: rgba(#333, 0.5)) {
- @include box-shadow(0 10px 5px -5px $color);
- position: relative;
- z-index: 1;
- &:before, &:after {
- @include box-shadow(0 10px 10px 1px $color);
- bottom: 2px;
- content: "";
- height: 10px;
- position: absolute;
- width: $width / 2;
- z-index: -1;
- }
- &:before {
- @include rotate(-$angle);
- left: 10px;
- }
- &:after {
- @include rotate($angle);
- right: 10px;
- }
-}
-
-// Sexy button !
-@mixin shiny-button($light-color: #92CE2F, $dark-mix-color: #32D17C, $mix-percent: 40%) {
- // Params
- $bg-light: $light-color;
- $bg-dark: darken(mix($dark-mix-color, $bg-light, $mix-percent), 13%);
-
- $border-inset-color: $bg-light;
- $border-inside-light: lighten($border-inset-color, 13%);
- $border-inside-dark: $border-inset-color;
-
- $border-outside: darken($bg-dark, 9%);
- $box-shadow: rgba(35, 35, 35, 0.2);
- $text-shadow: darken($bg-dark, 7%);
-
- @extend .bradius-inner;
- @include box-shadow(inset 1px 1px 0px $border-inside-light, inset -1px -1px 0px $border-inside-dark);
- @include gradient($bg-light, $bg-dark);
- @include text-shadow(2px 2px 1px $text-shadow);
- border:1px solid $border-outside;
- color:#FFF !important;
-
- font-size:size(13px);
- font-weight: bold;
- padding: 9px 60px;
- text-decoration: none;
- text-decoration: none !important;
- &:hover {
- @include box-shadow(inset 0px 0px 1px $border-inside-light, 0px 2px 1px $box-shadow);
- @include gradient(lighten($bg-light, 6%), lighten($bg-dark, 6%));
- }
- &:active {
- @include box-shadow(inset 0px 2px 3px $bg-dark);
- background: mix($bg-light, $bg-dark, 50%);
- }
- &.small {
- font-size: 12px;
- padding: 7px 22px;
- }
-}
-
-//
-// @TODO: Add docs to shiny-button-colors!
-//
-@mixin shiny-button-colors($light-color: #92CE2F, $dark-mix-color: #32D17C, $mix-percent: 40%) {
- // Params
- $bg-light: $light-color;
- $bg-dark: darken(mix($dark-mix-color, $bg-light, $mix-percent), 13%);
-
- $border-inset-color: $bg-light;
- $border-inside-light: lighten($border-inset-color, 13%);
- $border-inside-dark: $border-inset-color;
-
- $border-outside: darken($bg-dark, 9%);
- $box-shadow: rgba(35, 35, 35, 0.2);
- $text-shadow: darken($bg-dark, 7%);
-
-
- @include box-shadow(inset 1px 1px 0px $border-inside-light, inset -1px -1px 0px $border-inside-dark);
- @include gradient($bg-light, $bg-dark);
- @include text-shadow(2px 2px 1px $text-shadow);
- border:1px solid $border-outside;
- &:hover {
- @include box-shadow(inset 0px 0px 1px $border-inside-light, 0px 2px 1px $box-shadow);
- @include gradient(lighten($bg-light, 6%), lighten($bg-dark, 6%));
- }
- &:active {
- @include box-shadow(inset 0px 2px 3px $bg-dark);
- background: mix($bg-light, $bg-dark, 50%);
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_forms.scss b/app/assets/stylesheets/vendor/survival-kit/_forms.scss
deleted file mode 100644
index 7e82b87..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_forms.scss
+++ /dev/null
@@ -1,313 +0,0 @@
-// Survival ✚ Kit
-
-// A simple search box, generic.
-// If $width contains a second argument, it won't output the width to the parent element, allowing you to use box-size.
-//
-// <form action="#" accept-charset="utf-8" class="search-box">
-// <input type="text" class="text" value="Search..." name="q" />
-// <input type="submit" class="button" value="" />
-// </form>
-@mixin search-box-simple {
- // Preferences
- $width: 210px;
- $height: 27px;
- $font-size: 12px;
-
- background: #FFF;
- overflow: hidden;
- height: $height;
- width: $width;
-
- // Style
- border:1px solid #4BC5ED;
- margin-top: -3px;
- @extend .bradius-inner;
- @include gradient(#FFF, #F5F5F5);
-
- &.active {
- @include box-shadow(0px 1px 2px transparentize(#000, 0.8));
- background:#FFF;
- }
-
- // Calculations
- $button-width: 27px;
- $input-width: $width - $button-width - 2px;
-
- input, button {
- background:transparent;
- border: 0;
- font-size: $font-size;
- outline: none;
- }
- .text {
- @include size($input-width, $height, 7px 10px);
- color: #777;
- float: left;
- line-height: $height - (7px * 2);
- }
- button, .search {
- cursor: pointer;
- display: block;
- float:right;
- height: $height;
- padding:0;
- width: $button-width;
- }
- .search {
- background:transparent image-url('redesign/vendor/survival-kit/search-13x16.png') center center no-repeat;
- }
-}
-
-// Search Box Simple dimention override
-@mixin search-box-simple-size($width, $height, $button-width: 27px) {
- $input-width: $width - $button-width - 2px;
- height: $height;
- width: $width;
- .text {
- @include size($input-width, $height, 7px 10px);
- line-height: $height - (7px * 2);
- }
- button, .search {
- height: $height;
- width: $button-width;
- }
-}
-
-
-// Inputs.
-$input-shadow : inset 0 1px 2px rgba(0, 0, 0, 0.1), 0 1px 0 rgba(255, 255, 255, 0.2) !default;
-$input-hover-color : #7DBEF1 !default;
-$input-hover-shadow : 0 0 6px #7DBEF1 !default;
-
-//
-// Adds the Input state effects
-//
-@mixin input-effects() {
- @if $input-shadow { @include box-shadow($input-shadow); }
- border:1px solid #CCCCCC;
- outline: 0;
- &:focus {
- @if $input-hover-shadow {
- @include box-shadow($input-hover-shadow);
- }
- border:1px solid $input-hover-color;
- }
-}
-
-//
-// Forms Styles (Survival Kit)
-// This styles are meant to be used with Simple_Forms (Rails)
-// Usage:
-// simple-forms(default, option-1 option2)
-// Options:
-// block-hints : display the hints right after the inut field.
-@mixin simple-forms($selector : "simple_form", $opts:false) {
- // Setup
- $size-modifier : 0px;
- $input-width : 300px;
- $input-font-size : $base-font-size + $size-modifier;
- $vertical-spacing : 7px;
- $horizontal-spacing : 10px;
- $label-width :148px;
-
- // 7px = base padding at 0 size modifier.
- $vertical-field-padding : floor((7px + $size-modifier) + ($size-modifier / 4.4) * 2);
- $horizontal-field-padding: 6px;
-
- // Colors.
- $hint-color : #6E6E6E;
-
- @if $selector == auto or $selector == default {
- $selector: 'simple_form';
- }
-
- .hidden { display: none; }
- // Force $opts into a list goddamnit.
- $opts: join($opts, herp derp);
-
- .#{$selector} {
- @include debug;
- .hint {
- @include debug(green);
- display:inline-block;
- padding:$vertical-field-padding 0 $vertical-field-padding ($label-width + $horizontal-spacing);
- }
-
- // Fix a issue with the spacing.
- input.date {
- label {
- width: 145px !important;
- }
- }
-
-
- label {
- @include debug(green);
- vertical-align:middle;
- width:$label-width; // double line labels.
- display:inline-block; // works with already inline displayed items.
- margin:0 $horizontal-spacing 0 0;
- padding: $vertical-field-padding 0;
- line-height:$input-font-size + ($input-font-size * 0.26);
- text-align: right;
- abbr {
- @include debug(yellow);
- @if index($opts, no-stars) {
- display:none;
- } @else {
- color:#E62500;
- float: right;
- margin-left: $horizontal-spacing;
- }
- }
- &.boolean, &.collection_radio_buttons { padding:$horizontal-spacing/2; width: auto;}
- }
-
- .ext-sfr {
- @include debug(yellow);
- display: inline-block;
- vertical-align: middle;
- width: $label-width;
- }
-
- .input {
- @include debug(blue);
- padding:$vertical-spacing 0;
- .hint {
- @extend .ext-sfr;
- color: #8A8A8A;
- display: block;
- font-size: size(11px);
- padding: 2px 0 0 ($label-width + $horizontal-spacing);
- width: $input-width + ($horizontal-field-padding * 2) + $horizontal-spacing;
- }
- &.boolean {
- padding: 2px 0 0 ($label-width + $horizontal-spacing);
- }
- }
-
- select {
- border:1px solid #CCCCCC;
- outline:none;
- // floor(Font Size * Line Height) + (Vertical Input Padding * 2) + 1px)
- $calc: floor(($input-font-size * $base-line-height ) + ($vertical-field-padding * 2)) + (1px);
- height: $calc + 1px;
- padding:(6px + $size-modifier) * $base-line-height ;
- &:focus {
- border:1px solid $input-hover-color;
- }
- }
-
- // Needs to be nested so it doesn't collide with date selects.
- .select select, .country select {
- width:$input-width + ($horizontal-field-padding * 2);
- }
- textarea, input[type=text], input[type=password], input[type=email] {
- font-size:$input-font-size;
- padding: $vertical-field-padding $horizontal-field-padding;
- vertical-align:top;
- width:$input-width;
- // Input Effects
- @include input-effects;
- }
-
- textarea {
- height:80px;
- max-width:$input-width;
- }
-
- input {
- &.check_boxes, &.radio, &.boolean {
- vertical-align:middle;
- }
- }
-
- .submit, .padded {
- padding-left: $label-width + $horizontal-spacing;
- }
-
- .form-actions {
- background: #F7F7F7;
- border-top: 1px solid #DDD;
- padding: 17px 0px 18px $label-width + $horizontal-spacing;
- }
-
- // Simple Form Button for the forms.
- .button {
- @extend .sk-button;
- }
-
-
- // Errors @todo: this should be in its own section.
- span.error, .error {
- @extend .ext-sfr;
- color: #D65C5C;
- font-size: 12px;
- margin-left: 10px;
- }
-
- #error_explanation {
- @include box-shadow(#D4D4D4 0 0 10px);
- background: #FFEBD6;
- border: 1px solid #FFB36C;
- color:#895334;
- margin:$vertical-spacing * 4 0;
- padding: 10px 14px;
- h2 {
- @include header-size(18px);
- color:#AE4910;
- margin-top:0;
- }
- }
-
-
- // Colors for form validity
- input:valid, textarea:valid {}
-
- input:invalid, textarea:invalid {
- $error-color: #FF6161;
- box-shadow:$input-shadow, inset -7px 0px 0px lighten($error-color, 15%) !important;
- &:focus {
- @if $input-hover-shadow {
- @include box-shadow($input-hover-shadow, inset -7px 0px 0px $error-color !important );
- }
- }
- }
- }
-
- // Rails 3 wraps errors in Divs
- .field_with_errors {
- display:inline;
- }
-
- // Make this compatible when you have no javascript loaded!
- @if not index($opts, no-browser-support) {
- .ie7 {
- select { margin-top:15px;}
- }
- }
-}
-
-// Allows you to have different widths for different layouts.
-@mixin simple-form-width($width:false, $label-width:false) {
- $horizontal-field-padding : 6px;
- $horizontal-spacing : 3px;
- $input-width : $width;
-
- @if $width {
- textarea, input[type=text], input[type=password] {
- max-width: $width;
- width:$width;
- }
-
- .select select, .country select {
- width:$input-width + ($horizontal-field-padding * 2);
- }
- }
-
- @if $label-width {
- .input .hint {
- width:$label-width;
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_headers.scss b/app/assets/stylesheets/vendor/survival-kit/_headers.scss
deleted file mode 100644
index 8b99808..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_headers.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-// Survival ✚ Kit
-
-// Sets the font size specified in pixels using percents so that the base
-// font size changes and 1em has the correct value. When nesting font size
-// declarations, within the DOM tree, the base_font_size must be the parent's
-// effective font-size in pixels.
-// Usage Examples:
-// .big
-// +font-size(16px)
-// .bigger
-// +font-size(18px)
-// .big .bigger
-// +font-size(18px, 16px)
-//
-// For more information see the table found at http://developer.yahoo.com/yui/3/cssfonts/#fontsize
-// From: compass-html5-boilerplate gem.
-
-@function size($size, $base-font-size: $base-font-size) {
- @return ceil(percentage($size / $base-font-size));
-}
-
-
-// Calculate margin and line height according to the given size.
-@mixin header-size($size) {
- font-size: size($size);
-}
-
-// Calculate the Header based on the H1 Max size.
-@mixin htags-sizes($max) {
- $per: $max * 0.10;
- @for $i from 1 through 6 {
- h#{$i} {
- @include header-size($max - ($per * $i) );
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_images.scss b/app/assets/stylesheets/vendor/survival-kit/_images.scss
deleted file mode 100644
index 36e67cd..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_images.scss
+++ /dev/null
@@ -1,121 +0,0 @@
-// Survival ✚ Kit
-
-@import "compass/typography/text/replacement";
-
-// Replace an A tag with an a background-image.
-// @var $image string path to the image
-// @var $inline boolean embed via data.
-@mixin image-link($image, $inline:false) {
- @include image-background($image, $inline);
- cursor:pointer;
- @extend .ext-hide-text;
-}
-
-// Replace an A tag with an a background-image sprite. You need to provide it with
-// the dimentions of the image and the x-pos/y-pos
-//
-// @var $image string path to the image, inherit is useful.
-// @var $height width
-// @var $height pixels
-// @var $x-pos pixels
-// @var $y-pos pixels
-// @var $inline boolean embed via data.
-@mixin image-sprite-link($image, $width, $height, $x-pos, $y-pos, $inline: false) {
- @include sk-background(transparent, $image, $x-pos, $y-pos, no-repeat, $inline);
- width:$width;
- height:$height;
- @extend .ext-hide-text;
-}
-
-// Replace a Header>a tag with a background image. Made specifically for logos.
-// @var $image string path to the image
-// @var $inline boolean embed via data.
-@mixin logo($image, $inline:false) {
- @include no-mp;
- width: image-width($image);
- height: image-height($image);
- a {
- @include image-link($image, $inline);
- &:hover { opacity: 0.7;}
- }
-}
-
-// Area for a header link, meant to be used when it inherits a background image.
-// This should be invoked on the H1-6 Tag and not in the link, the needed structure is:2
-// <h1><a href=""></a></h1>
-@mixin logo-area($width, $height, $debugging: false) {
- @include no-mp;
- width:$width;
- height:$height;
- a {
- @include link-area($width, $height, $debugging);
- }
-}
-
-// An area which should be clickable. It's meant to be a low level mixin, you should
-// use the alternatuves.
-// - debugging enables a background color to know the position.
-@mixin link-area($width, $height, $debugging: false) {
- width:$width;
- height:$height;
- @if $debugging {
- @include debug($debugging);
- }
- @extend .ext-hide-text;
-}
-
-// Mixin for quickly replacing images for any given element.
-// @var $image string path to the image
-// @var $inline boolean embed via data.
-@mixin image-replace($image, $inline:false) {
- @include image-background($image, $inline);
- @extend .ext-hide-text;
-}
-@mixin image-replace-url($image, $width, $height) {
- background:transparent url($image) left top no-repeat;
- @include link-area($width, $height);
-}
-
-// Just adds the image as a background and sets the width/height accordingly.
-// @var $image string path to the image
-// @var $inline boolean embed via data.
-@mixin image-background($image, $inline:false) {
- @include sk-background(transparent, $image, no-repeat, top, left, $inline);
- width: image-width($image);
- height: image-height($image);
-}
-
-// Add a background by passing the exact same parameters as a normal one. With
-// one more parameter $inline. Which will use inline-image and add backward
-// compatibility to IE7 via *background.
-//
-// @var $color
-// @var $image string can be a path to an image or inherit (will insert tags separately)
-// @var $horizontal
-// @var $vertical
-// @var $repeat
-// @var $inline
-@mixin sk-background($color, $image, $horizontal, $vertical, $repeat, $inline: false) {
- @if $image == inherit {
- background-color: $color;
- background-repeat: $repeat;
- background-position: $horizontal $vertical;
- } @else {
- @if $inline == true {
- background : $color inline-image($image) $horizontal $vertical $repeat;
- *background : $color image-url($image) $horizontal $vertical $repeat;
- } @else {
- background: $color image-url($image) $horizontal $vertical $repeat;
- }
- }
-}
-
-
-// Common styles needed by our Image Mixins.
-// Depends on Compass.
-.ext-hide-text {
- @include hide-text;
- display:block;
- direction: ltr;
- outline:none;
-}
diff --git a/app/assets/stylesheets/vendor/survival-kit/_lists.scss b/app/assets/stylesheets/vendor/survival-kit/_lists.scss
deleted file mode 100644
index ea9670e..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_lists.scss
+++ /dev/null
@@ -1,37 +0,0 @@
-// Survival ✚ Kit
-
-// Add docs to float-list!
-@mixin float-list($side:left) {
- @include no-mp;
- list-style-type: none;
- li { float:$side; }
-}
-
-$tc-begin-color : #000 !default;
-$tc-end-color : lighten(#646464, 30) !default;
-$tc-base-font-size : 11px !default;
-$tc-max-font-size : 20px !default;
-$tc-how-many : 10 !default;
-@mixin tag-cloud($tc-begin-color, $tc-end-color, $tc-base-font-size, $tc-max-font-size, $tc-how-many) {
- $font-calculations : $tc-base-font-size;
-
- li {
- display:inline;
- background:none;
- padding:0 2px;
- }
-
- a {
- // Stops words from breaking.
- display:inline-block;
- }
-
- @for $i from 1 through $tc-how-many {
- // The last item gets the max-font size.
- $font-calculations: round($font-calculations + (($tc-max-font-size - $tc-base-font-size) / $tc-how-many));
- a.tag-#{$i} {
- font-size:$font-calculations;
- color: mix($tc-end-color, $tc-begin-color, ( $i * (100 / $tc-how-many) ));
- }
- }
-}
diff --git a/app/assets/stylesheets/vendor/survival-kit/_loader.scss b/app/assets/stylesheets/vendor/survival-kit/_loader.scss
deleted file mode 100644
index c09a018..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_loader.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-// Survival ✚ Kit
-
-// Load all the Libraries.
-@import "blog";
-@import "forms";
-@import "images";
-@import "lists";
-@import "navigation";
-@import "tools";
-@import "headers";
-@import "effects";
diff --git a/app/assets/stylesheets/vendor/survival-kit/_navigation.scss b/app/assets/stylesheets/vendor/survival-kit/_navigation.scss
deleted file mode 100644
index 5e6f13d..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_navigation.scss
+++ /dev/null
@@ -1,230 +0,0 @@
-// Survival ✚ Kit
-
-// Horizontal Navigation Low-level Method.
-//
-// It's meant to be called from other predifined mixins to avoid calling so many variables per call.
-// Used from ul/ol
-@mixin horizontal-navigation(
- $height,
- $color,
- $hover-color,
- $active-color,
- $text-shadow,
- $bg,
- $bg-hover,
- $bg-active,
- $box-shadow,
- $box-shadow-hover,
- $box-shadow-active,
- $border-left,
- $border-right,
- $padding,
- $margin,
- $border-radius,
- $font-weight,
- $font-size,
- $tab-space // Sets a tabbing space.
- ) {
- // $bg none or transparent will remove the background.
- @if $tab-space == none { $tab-space:0;}
- @if $bg == none { $bg:transparent;}
- @if $bg-active == auto { $bg-active:$bg-hover; }
- @if $active-color == auto { $active-color:$hover-color; }
-
- // Border Calculation
- // ----------------------------------------
- // Check if borders are set to anything but none / auto.
- @if $border-left != none and $border-right != none and $border-left != auto and $border-right != auto {
- // Borders where explicitly set.
- @include _sk-nav-borders($border-left, $border-right);
- } @else if $border-left == auto and $border-right == auto and $bg != transparent{
- // Borders calculated magically.
- @include _sk-nav-borders(lighten($bg, 10%), darken($bg, 10%));
- }
-
- height:$height; // instead of clearfix, to keep shadows alive.
- margin: 0;
- list-style:none;
-
- // Links and input
- li, a {
- display:block;
- float:left; // this can make it inline or block level.
- line-height:$height;
- }
-
-
- a {
- @if $font-weight != none {
- font-weight: $font-weight;
- }
- @if $padding != none {
- padding:$padding;
- }
- @if $margin != none {
- margin:$margin;
- }
- @if $font-size != none {
- font-size:$font-size;
- }
-
- text-decoration:none;
- color:$color;
-
- @if $bg != transparent {
- background:$bg;
- }
-
- @if $box-shadow != none {
- @include box-shadow($box-shadow);
- }
-
- @if $text-shadow != none {
- @include text-shadow($text-shadow, 1px, 1px, 1px);
- }
-
- @if $border-radius != none {
- @include border-radius($border-radius);
- }
-
- // Feature for tabs.
- @if $tab-space != 0 {
- margin-top: -($tab-space);
- }
-
- // States
- // ----------------------------------------
-
- &:hover{
- @include _sk-nav-effects($hover-color, $bg-hover, $text-shadow, $box-shadow-hover, $bg-hover);
- text-decoration:none;
- }
-
- &:visited {
- color:$active-color;
- }
- &.active {
- @include _sk-nav-effects($active-color, $bg-active, $text-shadow, $box-shadow-active, $bg-hover);
- // Add tab space.
- @if $tab-space != 0 {
- height:$height + $tab-space;
- }
- }
- }
-}
-
-// Mixin used to generate Background effects by the horizontal-navigation mixin.
-@mixin _sk-nav-effects($color, $bg, $text-shadow, $box-shadow, $bg-hover) {
- @if $color != auto {
- color:$color;
- }
- @if $bg != transparent {
- @if $bg-hover == auto {
- background:darken($bg,3%);
- } @else {
- background:$bg;
- }
- @if $box-shadow != none{
- @include box-shadow($box-shadow);
- }
- }
- // Remove the text shadow of hover.
- @if $text-shadow != none {
- @include text-shadow(none);
- }
-}
-
-// Low level mixin.
-// Invoked by other mixins.
-//
-// @var $left the left border.
-// @var $right the right border
-@mixin _sk-nav-borders($left, $right) {
- li:first-child, li.first {
- border-left:1px solid $right;
- }// li:first-child
- li:last-child, li.last {
- border-right:1px solid $left;
- }
- a {
- border:{
- left: 1px solid $left;
- right: 1px solid $right;
- };
- &.active, &.active:hover {
- border:{
- left:1px solid transparent;
- right:1px solid transparent;
- };
- }
- &:hover {
- border:{
- left:1px solid transparent;
- right:1px solid transparent;
- };
- }
- }
-}
-
-//
-// @TODO: Add docs to tabs!
-//
-@mixin navigation-classes($opts: tabs) {
- $opts: join($opts, force list);
- .nav {
- list-style: none;
- margin-bottom: $base-line-height;
- margin-left: 0;
- }
-
- // Make links block level
- .nav > li > a {
- display: block;
- }
- .nav > li > a:hover {
- background-color: #EEEEEE;
- text-decoration: none;
- }
-
- // Common styles
- .nav-tabs {
- @extend .nav;
- @include pie-clearfix();
- }
- .nav-tabs > li, .nav-pills > li {
- float: left;
- }
- .nav-tabs > li > a {
- line-height: 14px;
- margin-right: 2px;
- padding-left: 12px;
- padding-right: 12px; // keeps the overall height an even number
- }
-
- .nav-tabs {
- border-bottom: 1px solid #ddd;
- }
-
- .nav-tabs > li {
- margin-bottom: -1px;
- }
-
- .nav-tabs > li > a {
- @include border-radius(4px 4px 0 0);
- border: 1px solid transparent;
- padding-bottom: 9px;
- padding-top: 9px;
- &:hover {
- border-color: #EEEEEE #EEEEEE #ddd;
- }
- }
- .nav-tabs > .active {
- a, a:hover {
- background-color: #FFF;
- border: 1px solid #ddd;
- border-bottom-color: transparent;
- color: gray;
- cursor: default;
- }
- }
-} \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_secure.scss b/app/assets/stylesheets/vendor/survival-kit/_secure.scss
deleted file mode 100644
index f08dd11..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_secure.scss
+++ /dev/null
@@ -1,3 +0,0 @@
-/*!
- This is a compiled file.
-*/ \ No newline at end of file
diff --git a/app/assets/stylesheets/vendor/survival-kit/_tools.scss b/app/assets/stylesheets/vendor/survival-kit/_tools.scss
deleted file mode 100644
index e753dfe..0000000
--- a/app/assets/stylesheets/vendor/survival-kit/_tools.scss
+++ /dev/null
@@ -1,267 +0,0 @@
-// Survival ✚ Kit
-$container-width : 1000px !default;
-$compatibility-mode : true, ie ie7 ie8 ie9 ff2 chrome9 !default;
-
-// Function to know if we're in compatibility mode, if $version is set it'll return if there's a match for that browser.
-@function in-compatibility-mode($version: false) {
- @if $compatibility-mode {
- @if $version {
- @return index(nth($compatibility-mode, 2), $version);
- } @else {
- @return nth($compatibility-mode, 1);
- }
- } @else {
- @return false;
- }
-}
-
-// Shortcut to remove margin an padding.
-// Used on several @mixins.
-@mixin no-mp($extend:false) {
- @if $extend {
- @extend .no-mp;
- } @else {
- margin:0;
- padding:0;
- }
-}
-// Sometimes it's better to extend a class.
-.no-mp {
- margin:0;
- padding:0;
-}
-
-// Center an element.
-@mixin center-container($container-width, $vertical-margin:0, $padding:0) {
- margin:$vertical-margin auto;
- @if $padding == 0 {
- width:$container-width;
- } @else {
- @include size($container-width, auto, $padding);
- }
-}
-
-// Inline Block CrossBrowser.
-// Disregards FF2 and IE6
-@mixin inline-block {
- display: inline-block;
- @if in-compatibility-mode(ie7) {
- zoom: 1;
- *display:inline;
- }
-}
-
-// Shortcut to set absolute positioning.
-@mixin pos($pos, $debug: false) {
- @if length($pos) == 1 {
- $pos: $pos 0 0 0;
- }
- @if length($pos) == 2 {
- $pos: nth($pos,1) nth($pos,2) 0 0;
- }
- @if length($pos) == 3 {
- $pos: nth($pos,1) nth($pos,2) nth($pos, 3) 0;
- }
- position:absolute;
- @if "#{nth($pos, 1)}" != "0" { top: nth($pos, 1); }
- @if "#{nth($pos, 2)}" != "0" { right: nth($pos, 2); }
- @if "#{nth($pos, 3)}" != "0" { bottom: nth($pos, 3); }
- @if "#{nth($pos, 4)}" != "0" { left: nth($pos, 4); }
- @if $debug { @include debug($debug); }
-}
-
-// Center a absolute element horizontally; optional offset.
-@mixin pos-x-center($width, $offset:0) {
- @include pos(0 50% 0 50%);
- margin-left:$offset - ( $width / 2 );
- width:$width;
-}
-
-// Center a absolute element vertically; optional offset.
-@mixin pos-y-center($height, $offset:0) {
- @include pos(50% 0 50% 0);
- height:$height;
- margin-top:$offset - ( $height / 2 );
-}
-
-// Set a debug variable.
-@mixin debug($color:red) {
- @if $debug != false {
- @if $color == true { $color:red; }
- background: rgba($color, 0.2); // incompatible with IE.
- }
-}
-
-// Class available to center container to 1000px
-.w, .pagewidth {
- @include center-container($container-width);
-}
-
-// Crossbrowser linear gradient.
-// Compatible Browsers: FF3.6+ Saf4+ Chrome IE6-IE9
-// @author SitePoint
-@mixin background-gradient($from, $to, $start: top, $end: bottom, $fallback:$from, $ie:false) {
- @include gradient($from, $to, $start, $end, $fallback);
-}
-@mixin gradient($from, $to, $start: top, $end: bottom, $fallback:$from){
- background-color: $fallback;
-
- @if $end == bottom and $start == top {
- @if $start == 0 {
- background-image: -webkit-gradient(linear, left $start, left bottom, from($from), to($to));
- } @else {
- background-image: -webkit-gradient(linear, $start, left bottom, from($from), to($to));
- }
- background-image: -webkit-linear-gradient($start, $from, $to);
- background-image: -moz-linear-gradient($start, $from, $to);
- background-image: -ms-linear-gradient($start, $from, $to);
- background-image: -o-linear-gradient($start, $from, $to);
- @if in-compatibility-mode() {
- filter: progid:DXImageTransform.Microsoft.gradient(startColorStr='#{ie-hex-str($from)}', EndColorStr='#{ie-hex-str($to)}');
- }
- } @else if $end == bottom {
- background-image: -webkit-gradient(linear, left $start, 0 $end, from($from), to($to));
- background-image: -webkit-linear-gradient(top, $from $start+px, $to);
- background-image: -moz-linear-gradient(top, $from $start+px, $to);
- background-image: -ms-linear-gradient(top, $from $start+px, $to);
- background-image: -o-linear-gradient(top, $from $start+px, $to);
-
- } @else {
- background-image: -webkit-gradient(linear, left $start, 0 $end, from($from), to($to));
- background-image: -webkit-linear-gradient(top, $from $start+px, $to $end+px);
- background-image: -moz-linear-gradient(top, $from $start+px, $to $end+px);
- background-image: -ms-linear-gradient(top, $from $start+px, $to $end+px);
- background-image: -o-linear-gradient(top, $from $start+px, $to $end+px);
- // No IE support for positioned gradients
- }
-}
-
-// Mixin that allows you to set the size of the box to a fixed width/height
-// taking into consideration the padding and borders for you.
-//
-// Examples:
-// @include size(100px, 100px, 10px, 5px solid red);
-// Will render a 100x100.
-//
-// $width: Pixel value for width
-// $height: Pixel value for height
-// $padding: Padding accepts: 1px or 1px 2px or 1px 2px 3px 4px
-// $border: Border, accepts 1px solid #000 or 1px or 1px 2px or 1px 2px 3px 4px
-// When passing a border declaration (1px solid #000) it'll add the CSS for you.
-@mixin size($width, $height:auto, $padding: none, $border:none) {
- // Prepare the borders, accept the following:
- // 1px solid #000 or 1px or 1px 2px or 1px 2px 3px 4px
- @if true {
- @if $border == none {
- $border:0;
- }
-
- $border-len: length($border);
- // Standardize padding to a list with 4 items.
- @if $border-len == 3 {
- border:$border;
- $bw: nth($border, 1);
- $border: $bw $bw $bw $bw;
- } @else if $border-len == 1 {
- $border: $border $border $border $border;
- } @else if $border-len == 2 {
- $border: join($border, $border);
- }
- }
-
- // Prepare padding, accept the following:
- // 1px or 1px 2px or 1px 2px 3px 4px
- @if true {
- @if $padding == none {
- $padding:0;
- } @else {
- padding:$padding;
- }
-
- // Standardize padding to a list with 4 items.
- $padding-len: length($padding);
- @if $padding-len == 1 {
- $padding: $padding $padding $padding $padding;
- } @else if $padding-len == 2 {
- $padding: join($padding, $padding);
- }
- }
-
- @if $width != auto {
- width: $width - (nth($padding, 2) + nth($padding, 4)) - (nth($border, 2) + nth($border, 4));
- }
- @if $height != auto {
- height: $height - (nth($padding, 1) + nth($padding, 3)) - (nth($border, 1) + nth($border, 3));
- }
-}
-
-// Float an element with a given width and a direction. Third parameter allows easy debugging.
-// Yes, we override Compass :(
-// @TODO: Make it use box-size and allow padding.
-@mixin float($side, $size:auto, $debug-color:false) {
- @if $size != auto {
- @if length($size) == 1 {
- width:$size;
- } @else {
- height:nth($size, 2);
- width:nth($size, 1);
- }
-
- }
- @if in-compatibility-mode(ie6) {
- display:inline;
- }
- float: $side;
- @if $debug-color and $debug {
- @include debug($debug-color);
- }
-}
-
-@mixin transition($property: all, $time: 400ms, $easing: ease-out){
- transition: $property $time $easing;
- -moz-transition: $property $time $easing;
- -ms-transition: $property $time $easing;
- -o-transition: $property $time $easing;
- -webkit-transition: $property $time $easing;
-}
-
-// Calculate the Golden Ratio of a given value.
-// ----------------------------------------
-@function golden-ratio($size, $type) {
- $big : round($size / 1.61803);
- $small : $size - $big;
- @return if($type == large, $big, $small);
-}
-
-
-//
-// @TODO: Add docs to link-colors!
-//
-@mixin link-colors($normal, $hover: false, $active: false, $visited: false, $focus: false) {
- @if $normal == default {
- $hover: $link-hover-color;
- $normal: $link-color;
- $visited: $link-visited-color;
- }
- color: $normal;
- @if $visited {
- &:visited {
- color: $visited; } }
- @if $focus {
- &:focus {
- color: $focus; } }
- @if $hover {
- &:hover {
- color: $hover; } }
- @if $active {
- &:active {
- color: $active; } }
-}
-
-// Substract the Body to the Container width to get the sidebar.
-@function sidebar($body-width, $container-width-over: false) {
- @if $container-width-over == false {
- $container-width-over : $container-width;
- }
- @return $container-width - $body-width;
-} \ No newline at end of file
diff --git a/app/controllers/api/rows_controller.rb b/app/controllers/api/rows_controller.rb
index 6e815eb..543aebe 100644
--- a/app/controllers/api/rows_controller.rb
+++ b/app/controllers/api/rows_controller.rb
@@ -84,7 +84,7 @@ class Api::RowsController < ApplicationController
private
def check_remote_ip_address_whitelist
- if !(REMOTE_IP_ADDRESS_WHITELIST.empty? or REMOTE_IP_ADDRESS_WHITELIST.include?(ENV['REMOTE_ADDR']))
+ if !(GsParameter.get('REMOTE_IP_ADDRESS_WHITELIST').empty? or GsParameter.get('REMOTE_IP_ADDRESS_WHITELIST').include?(ENV['REMOTE_ADDR']))
redirect_to root_url
end
end
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index c675f5c..e4165f3 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -54,8 +54,8 @@ class ApplicationController < ActionController::Base
# Generate a new random PIN
#
def random_pin
- if MINIMUM_PIN_LENGTH > 0
- (1..MINIMUM_PIN_LENGTH).map{|i| (0 .. 9).to_a.sample}.join
+ if GsParameter.get('MINIMUM_PIN_LENGTH') > 0
+ (1..GsParameter.get('MINIMUM_PIN_LENGTH')).map{|i| (0 .. 9).to_a.sample}.join
end
end
diff --git a/app/controllers/call_forwards_controller.rb b/app/controllers/call_forwards_controller.rb
index 5321b35..001ed60 100644
--- a/app/controllers/call_forwards_controller.rb
+++ b/app/controllers/call_forwards_controller.rb
@@ -21,10 +21,10 @@ class CallForwardsController < ApplicationController
def new
@call_forward = @phone_number.call_forwards.build
- @call_forward.depth = DEFAULT_CALL_FORWARD_DEPTH
+ @call_forward.depth = GsParameter.get('DEFAULT_CALL_FORWARD_DEPTH')
@call_forward.active = true
@call_forwarding_destinations = call_forwarding_destination_types()
- @call_forward.destination = CALLFORWARD_DESTINATION_DEFAULT.to_s if defined?(CALLFORWARD_DESTINATION_DEFAULT)
+ @call_forward.destination = GsParameter.get('CALLFORWARD_DESTINATION_DEFAULT').to_s if defined?(GsParameter.get('CALLFORWARD_DESTINATION_DEFAULT'))
@available_call_forward_cases = []
CallForwardCase.all.each do |available_call_forward_case|
diff --git a/app/controllers/call_histories_controller.rb b/app/controllers/call_histories_controller.rb
index f956f88..5335ed3 100644
--- a/app/controllers/call_histories_controller.rb
+++ b/app/controllers/call_histories_controller.rb
@@ -22,7 +22,7 @@ class CallHistoriesController < ApplicationController
@call_histories = calls.paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
@calls_count = calls.count
@@ -34,6 +34,8 @@ class CallHistoriesController < ApplicationController
if ! @type.blank?
@call_histories = @call_histories.where(:entry_type => @type)
end
+
+ @call_histories = @call_histories.order(:created_at).reverse_order.limit(1000)
end
diff --git a/app/controllers/call_routes_controller.rb b/app/controllers/call_routes_controller.rb
new file mode 100644
index 0000000..0259a10
--- /dev/null
+++ b/app/controllers/call_routes_controller.rb
@@ -0,0 +1,75 @@
+class CallRoutesController < ApplicationController
+ authorize_resource :call_route
+
+ def index
+ @call_routes = CallRoute.order([:routing_table, :position])
+ @routing_tables = @call_routes.pluck(:routing_table).uniq.sort
+ spread_breadcrumbs
+ end
+
+ def show
+ @call_route = CallRoute.find(params[:id])
+ spread_breadcrumbs
+ end
+
+ def new
+ @call_route = CallRoute.new
+ spread_breadcrumbs
+ end
+
+ def create
+ @call_route = CallRoute.new(call_route_parameter_params)
+ spread_breadcrumbs
+ if @call_route.save
+ redirect_to @call_route, :notice => t('call_routes.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @call_route = CallRoute.find(params[:id])
+ spread_breadcrumbs
+ end
+
+ def update
+ @call_route = CallRoute.find(params[:id])
+ spread_breadcrumbs
+ if @call_route.update_attributes(call_route_parameter_params)
+ redirect_to @call_route, :notice => t('call_routes.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @call_route = CallRoute.find(params[:id])
+ @call_route.destroy
+ redirect_to call_routes_url, :notice => t('call_routes.controller.successfuly_destroyed')
+ end
+
+ def move_higher
+ @call_route = CallRoute.find(params[:id])
+ @call_route.move_higher
+ redirect_to :back
+ end
+
+ def move_lower
+ @call_route = CallRoute.find(params[:id])
+ @call_route.move_lower
+ redirect_to :back
+ end
+
+ private
+ def call_route_parameter_params
+ params.require(:call_route).permit(:routing_table, :name, :endpoint_type, :endpoint_id)
+ end
+
+ def spread_breadcrumbs
+ add_breadcrumb t("call_routes.index.page_title"), call_routes_path
+ if @call_route && !@call_route.new_record?
+ add_breadcrumb @call_route, @call_route
+ end
+ end
+
+end
diff --git a/app/controllers/conferences_controller.rb b/app/controllers/conferences_controller.rb
index 302a23b..6091b46 100644
--- a/app/controllers/conferences_controller.rb
+++ b/app/controllers/conferences_controller.rb
@@ -19,7 +19,7 @@ class ConferencesController < ApplicationController
@conference.start = nil
@conference.end = nil
@conference.open_for_anybody = true
- @conference.max_members = DEFAULT_MAX_CONFERENCE_MEMBERS
+ @conference.max_members = GsParameter.get('DEFAULT_MAX_CONFERENCE_MEMBERS')
@conference.pin = random_pin
@conference.open_for_anybody = true
diff --git a/app/controllers/config_siemens_controller.rb b/app/controllers/config_siemens_controller.rb
index c09dfcf..b7fa107 100644
--- a/app/controllers/config_siemens_controller.rb
+++ b/app/controllers/config_siemens_controller.rb
@@ -64,8 +64,8 @@ class ConfigSiemensController < ApplicationController
if mac_address
@phone = Phone.find_by_mac_address(mac_address.gsub(':','').upcase)
- if ! @phone && PROVISIONING_AUTO_ADD_PHONE
- tenant = Tenant.where(:id => PROVISIONING_AUTO_TENANT_ID).first
+ if ! @phone && GsParameter.get('PROVISIONING_AUTO_ADD_PHONE')
+ tenant = Tenant.where(:id => GsParameter.get('PROVISIONING_AUTO_TENANT_ID')).first
if ! tenant
render(
:status => 404,
@@ -91,12 +91,12 @@ class ConfigSiemensController < ApplicationController
return
end
- if ! PROVISIONING_AUTO_ADD_SIP_ACCOUNT
+ if ! GsParameter.get('PROVISIONING_AUTO_ADD_SIP_ACCOUNT')
return
end
caller_name_index = 0
- sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}%").sort { |item1, item2|
+ sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{GsParameter.get('PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX')}%").sort { |item1, item2|
item1.caller_name.gsub(/[^0-9]/, '').to_i <=> item2.caller_name.gsub(/[^0-9]/, '').to_i
}.last
@@ -106,18 +106,18 @@ class ConfigSiemensController < ApplicationController
caller_name_index = caller_name_index + 1
@sip_account = tenant.sip_accounts.build
- @sip_account.caller_name = "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}#{caller_name_index}"
- @sip_account.call_waiting = CALL_WAITING
- @sip_account.clir = DEFAULT_CLIR_SETTING
- @sip_account.clip = DEFAULT_CLIP_SETTING
+ @sip_account.caller_name = "#{GsParameter.get('PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX')}#{caller_name_index}"
+ @sip_account.call_waiting = GsParameter.get('CALL_WAITING')
+ @sip_account.clir = GsParameter.get('DEFAULT_CLIR_SETTING')
+ @sip_account.clip = GsParameter.get('DEFAULT_CLIP_SETTING')
@sip_account.voicemail_pin = random_pin
- @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT
+ @sip_account.callforward_rules_act_per_sip_account = GsParameter.get('CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT')
@sip_account.hotdeskable = false
loop do
- @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME)
+ @sip_account.auth_name = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_AUTH_NAME'))
break unless SipAccount.exists?(:auth_name => @sip_account.auth_name)
end
- @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD)
+ @sip_account.password = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_PASSWORD'))
if ! @sip_account.save
render(
@@ -439,7 +439,7 @@ class ConfigSiemensController < ApplicationController
@new_settings << ['XML-app-debug-prog-name', 2, '']
@new_settings << ['XML-app-num-tabs', 2, '3']
@new_settings << ['XML-app-restart', 2, 'true']
- @new_settings << ['XML-app-tab1-display-name', 2, "Gemeinschaft #{GEMEINSCHAFT_VERSION}"]
+ @new_settings << ['XML-app-tab1-display-name', 2, "Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}"]
@new_settings << ['XML-app-tab1-name', 2, 'menu']
@new_settings << ['XML-app-tab2-display-name', 2, 'Status']
@new_settings << ['XML-app-tab2-name', 2, 'menu_status']
@@ -816,7 +816,7 @@ class ConfigSiemensController < ApplicationController
auto_reload_time = 60
- SIEMENS_HISTORY_RELOAD_TIMES.each_pair do |time_range, reload_value|
+ GsParameter.get('SIEMENS_HISTORY_RELOAD_TIMES').each_pair do |time_range, reload_value|
if time_range === Time.now.localtime.hour
auto_reload_time = reload_value
end
diff --git a/app/controllers/config_siemens_sort_controller.rb b/app/controllers/config_siemens_sort_controller.rb
deleted file mode 100644
index c0739e5..0000000
--- a/app/controllers/config_siemens_sort_controller.rb
+++ /dev/null
@@ -1,371 +0,0 @@
-require 'nokogiri'
-#doc.search('Message/ItemList').each do |a| puts a.children end
-class ConfigSiemensController < ApplicationController
-#TODO Authentication
- # No access for admins though as this contains personal data.
-
- # We can't use load_and_authorize_resource() here because
- # ConfigSiemensController isn't a resource.
- # We can try client certificates
-
- skip_authorization_check
-
-
- def index
- os40_keys=7
- os60_keys=8
- os80_keys=9
- doc = Nokogiri::XML(request.body.read)
- #logger.debug("#{params[:WorkpointMessage].to_xml}")
- #logger.debug("#{params[:WorkpointMessage][:Message][:ItemList].to_xml}")
- @phone_items=Hash.new
- contact_reason = params[:WorkpointMessage][:Message][:ReasonForContact]
- reply_status = doc.search('Message/ReasonForContact').first[:status]
- reply_action = doc.search('Message/ReasonForContact').first[:action]
-
- doc.search('Message/ItemList/Item').each do |post_item|
- @phone_items[post_item[:name]]=post_item.children.to_s
- end
-
- mac_address = @phone_items['mac-addr']
- phone_type = @phone_items['device-type']
- if phone_type == "OpenStage 40"
- max_keys = (os40_keys) * 2
- elsif phone_type == "OpenStage 60"
- max_keys = (os60_keys) * 2
- elsif phone_type == "OpenStage 80"
- max_keys = (os80_keys) * 2
- else
- max_keys = 0
- end
-
- blf_keys_max = max_keys / 2
- shift_key_position = blf_keys_max - 1
-
- #logger.debug(request.body.read)
- @phone = Phone.find_by_mac_address(mac_address.gsub(':','').upcase)
- if ! @phone.nil?
- @phone.update_attributes(:ip_address => request.remote_ip)
- sip_account = SipAccount.where(:sip_accountable_type == @phone.phoneable_type,
- :sip_accountable_id == @phone.phoneable_id).first
- end
-
- if ! @phone.nil? && ! sip_account.nil?
- #logger.debug(@phone_items)
- @my_nonce = params[:WorkpointMessage][:Message][:nonce]
- @new_settings = Array.new
-
- @new_settings << ['dhcp', nil, 'true']
- @new_settings << ['hostname', nil, mac_address.gsub(':', '') ]
- @new_settings << ['e164-hostname', nil, 'false']
- @new_settings << ['mobility-enabled', nil, 'false']
- @new_settings << ['mobility-password-on-logoff', nil, 'false']
- @new_settings << ['e164', nil, sip_account.try(:phone_numbers).first.number]
- @new_settings << ['sip-user-id', nil, sip_account.auth_name]
- @new_settings << ['reg-id', nil, sip_account.auth_name]
- @new_settings << ['reg-number', nil, sip_account.auth_name]
- @new_settings << ['fully-qualified-phone-no', nil, sip_account.auth_name]
- @new_settings << ['sip-pwd', nil, sip_account.password]
- @new_settings << ['sip-name', nil, sip_account.caller_name]
- @new_settings << ['register-by-name', nil, 'false']
- #OPTIMIZE Display ID ?
- @new_settings << ['display-id', nil, sip_account.try(:phone_numbers).first.number]
- @new_settings << ['display-id-unicode', nil, sip_account.caller_name]
- @new_settings << ['use-display-id', nil, 'true']
- @new_settings << ['reg-addr', nil, sip_account.sip_domain.host]
- @new_settings << ['reg-port', nil, '5060']
- @new_settings << ['registrar-addr', nil, sip_account.sip_domain.host]
- @new_settings << ['registrar-port', nil, '5060']
- @new_settings << ['outbound-proxy', nil, sip_account.sip_domain.host]
- @new_settings << ['outbound-proxy-user', nil, sip_account.sip_domain.host]
- @new_settings << ['sgnl-gateway-addr', nil, sip_account.sip_domain.host]
- @new_settings << ['sgnl-gateway-addr-user', nil, sip_account.sip_domain.host]
- @new_settings << ['sgnl-gateway-port', nil, '5060' ]
- @new_settings << ['sgnl-gateway-port-user', nil, '5060']
- @new_settings << ['sgnl-route', nil, '0' ]
- @new_settings << ['mwi-e164', nil, '' ]
- @new_settings << ['rtp-base-port', nil, '5004']
- @new_settings << ['default-domain', nil, '' ]
- @new_settings << ['sip-transport', nil, '0' ]
- @new_settings << ['sip-transport-user', nil, '0' ]
- @new_settings << ['server-type', nil, '0' ]
- @new_settings << ['session-timer', nil, 'true']
- @new_settings << ['session-duration', nil, '3600' ]
- @new_settings << ['reg-ttl', nil, '3600' ]
- @new_settings << ['realm', nil, sip_account.sip_domain.realm]
- @new_settings << ['emergency-e164', nil, '0110' ]
- @new_settings << ['voice-mail-e164', nil, 'voicemail']
- @new_settings << ['auto-answer', nil, 'false']
- @new_settings << ['beep-on-auto-answer', nil, 'true']
- @new_settings << ['auto-reconnect', nil, 'false' ]
- @new_settings << ['beep-on-auto-reconnect', nil, 'true']
- @new_settings << ['permit-decline-call', nil, 'true']
- @new_settings << ['transfer-on-ring', nil, 'false' ]
- @new_settings << ['join-allowed-in-conference', nil, 'true']
- @new_settings << ['pickup-group-uri', nil, '*8*']
- @new_settings << ['pickup-group-uri', nil, '' ]
- @new_settings << ['hot-line-warm-line-digits', nil, '' ]
- @new_settings << ['initial-digit-timer', nil, '30' ]
- @new_settings << ['conference-factory-uri', nil, '']
- @new_settings << ['callback-busy-allow', nil, 'false']
- @new_settings << ['callback-busy-code', nil, '' ]
- @new_settings << ['callback-ring-allow', nil, 'false']
- @new_settings << ['callback-ring-code', nil, '']
- @new_settings << ['callback-cancel-code', nil, '']
- @new_settings << ['park-server', nil, '']
- #OPTIMIZE Callwaiting
- @new_settings << ['call-waiting-enabled', nil, 'true']
- @new_settings << ['qos-layer2', nil, 'true']
- @new_settings << ['l2qos-voice', nil, '5' ]
- @new_settings << ['l2qos-signalling', nil, '3' ]
- @new_settings << ['l2qos-default', nil, '0']
- @new_settings << ['qos-layer3', nil, 'true']
- @new_settings << ['l3qos-voice', nil, '46']
- @new_settings << ['l3qos-signalling', nil, '26']
- @new_settings << ['vlan-method', nil, '1']
- #OPTIMIZE Timezone
- @new_settings << ['sntp-tz-offset', nil, '']
- @new_settings << ['daylight-save', nil, '']
- @new_settings << ['daylight-save-minutes', nil, '']
- #OPTIMIZE Use SNMP?
- @new_settings << ['snmp-trap-addr', nil, '']
- @new_settings << ['snmp-trap-port', nil, '']
- @new_settings << ['snmp-trap-pwd', nil, 'snmp' ]
- @new_settings << ['snmp-traps-active', nil, 'false' ]
- @new_settings << ['diagnostic-trap-addr', nil, '']
- @new_settings << ['diagnostic-trap-port', nil, '']
- @new_settings << ['diagnostic-trap-pwd', nil, 'snmp' ]
- @new_settings << ['diagnostic-traps-active', nil, 'false' ]
- @new_settings << ['diagnostic-snmp-active', nil, 'false']
- @new_settings << ['qdc-collection-unit-addr', nil, '']
- @new_settings << ['qdc-collection-unit-port', nil, '12010']
-
- @new_settings << ['qdc-trap-pwd', nil, 'QOSDC']
- @new_settings << ['qdc-snmp-active', nil, 'false']
- @new_settings << ['qdc-qcu-active', nil, 'false']
- @new_settings << ['snmp-queries-allowed', nil, 'false']
- @new_settings << ['snmp-pwd', nil, '']
- @new_settings << ['disable-microphone', nil, 'false']
- @new_settings << ['loudspeech-enabled', nil, 'true']
- @new_settings << ['audio-silence-suppression', nil, 'false']
-
- @new_settings << ['port1', nil, '0' ] # 0=Automatic (speed)
- @new_settings << ['port2', nil, '0' ]
- @new_settings << ['port2-mode', nil, '1' ]
- @new_settings << ['port2-auto-mdix-enabled', nil, 'true' ]
- @new_settings << ['originating-line-preference', nil, '0']
- @new_settings << ['terminating-line-preference', nil, '0']
- @new_settings << ['line-key-operating-mode', nil, '0']
- @new_settings << ['line-rollover-type', nil, '2']
- @new_settings << ['line-rollover-volume', nil, '5' ]# 1-5
- @new_settings << ['line-registration-leds', nil, 'true']
- @new_settings << ['keyset-use-focus', nil, 'true' ]
- @new_settings << ['keyset-remote-forward-ind', nil, 'true']
- @new_settings << ['keyset-reservation-timer', nil, '60' ] # 0-300
- @new_settings << ['dial-plan-enabled', nil, '' ]
- @new_settings << ['Canonical-dialing-international-prefix', nil, '']
- @new_settings << ['Canonical-dialing-local-country-code', nil, '']
- @new_settings << ['Canonical-dialing-national-prefix', nil, '']
- @new_settings << ['Canonical-dialing-local-area-code', nil, '']
- @new_settings << ['Canonical-dialing-local-node', nil, '']
- @new_settings << ['Canonical-dialing-external-access', nil, '0']
- @new_settings << ['Canonical-dialing-operator-code', nil, '']
- @new_settings << ['Canonical-dialing-emergency-number', nil, '']
- @new_settings << ['Canonical-dialing-dial-needs-access-code', nil, '0']
- @new_settings << ['Canonical-dialing-dial-needs-intGWcode', nil, '0']
- @new_settings << ['Canonical-dialing-min-local-number-length', nil, '10']
- @new_settings << ['Canonical-dialing-extension-initial-digits', nil, '']
- @new_settings << ['Canonical-dialing-dial-internal-form', nil, '0' ]
- @new_settings << ['Canonical-dialing-dial-external-form', nil, '0' ]
- @new_settings << ['Canonical-lookup-local-code', nil, '' ]
- @new_settings << ['Canonical-lookup-international-code', nil, '']
- @new_settings << ['hot-keypad-dialing', nil, '']
- @new_settings << ['ldap-transport', nil, '0']
- @new_settings << ['ldap-server-address', nil, '' ]
- @new_settings << ['ldap-server-port', nil, '389' ]
- @new_settings << ['ldap-authentication', nil, '1']
- @new_settings << ['ldap-user', nil, '' ]
- @new_settings << ['ldap-pwd', nil, '' ]
- @new_settings << ['ldap-max-responses', nil, '25']
- @new_settings << ['backup-addr', nil, '']
- @new_settings << ['backup-registration', nil, 'false']
- @new_settings << ['qdc-qcu-active', nil, 'false' ]
- @new_settings << ['min-admin-passw-length', nil, '6' ]
- @new_settings << ['default-locked-config-menus', nil, 'true' ]
- @new_settings << ['locked-config-menus', nil, 'true' ]
- @new_settings << ['default-locked-local-function-menus', nil, 'true' ]
- @new_settings << ['locked-local-function-menus', nil, 'true' ]
- @new_settings << ['dls-mode-secure', nil, '0' ]
- @new_settings << ['dls-chunk-size', nil, '9492']
- @new_settings << ['default-passw-policy', nil, 'false']
- @new_settings << ['deflect-destination', nil, '']
- @new_settings << ['display-skin', nil, '']
- @new_settings << ['enable-bluetooth-interface', nil, 'true']
- @new_settings << ['usb-access-enabled', nil, 'false' ]
- @new_settings << ['usb-backup-enabled', nil, 'false' ]
- @new_settings << ['line-button-mode', nil, '0' ]
- @new_settings << ['lock-forwarding', nil, '' ]
- @new_settings << ['loudspeaker-function-mode', nil, '0' ]
- @new_settings << ['max-pin-retries', nil, '' ]
- @new_settings << ['inactivity-timeout', nil, '30' ]
- @new_settings << ['not-used-timeout', nil, '2' ]
- @new_settings << ['passw-char-set', nil, '0' ]
- @new_settings << ['refuse-call', nil, 'true' ]
- @new_settings << ['restart-password', nil, '']
- #OPTIMIZE clock format
- @new_settings << ['time-format', nil, '0' ]# 1=12 h
- @new_settings << ['uaCSTA-enabled', nil, 'false' ]
- @new_settings << ['enable-test-interface', nil, 'false']
- @new_settings << ['enable-WBM', nil, 'true']
- @new_settings << ['pixelsaver-timeout', nil, '2' ]# 2 hours?
- @new_settings << ['voice-message-dial-tone', nil, '' ]
- @new_settings << ['call-pickup-allowed', nil, 'true' ]
- @new_settings << ['group-pickup-tone-allowed', nil, 'true']
- @new_settings << ['group-pickup-as-ringer', nil, 'false']
- @new_settings << ['group-pickup-alert-type', nil, '0' ]
- @new_settings << ['default-profile', nil, '' ]
- @new_settings << ['count-medium-priority', nil, '5']
- @new_settings << ['timer-medium-priority', nil, '60'] # 1 - 999
- @new_settings << ['timer-high-priority', nil, '5'] # 0 - 999
- @new_settings << ['dss-sip-detect-timer', nil, '10']
- @new_settings << ['dss-sip-deflect', nil, 'false' ]
- @new_settings << ['dss-sip-refuse', nil, 'false' ]
- @new_settings << ['feature-availability', nil, 'false']
- @new_settings << ['feature-availability', nil, 'true' ]
- @new_settings << ['feature-availability', nil, 'true' ]
- @new_settings << ['local-control-feature-availability', nil, 'false' ]
- @new_settings << ['trace-level', nil, '0' ] # Off
- @new_settings << ['default-locked-function-keys', nil, 'true' ]# "unknown item"
- #OPTIMIZE Put pickup prefix into database/global constant?
- @new_settings << ['blf-code', nil, 'f_ia_'] # pickup prefix for softkey function 59 (BLF)
- @new_settings << ['stimulus-feature-code', nil, true]
- @new_settings << ['stimulus-led-control-uri', nil, true]
-
-
- @new_settings << ['min-user-passw-length', nil, '6' ]# 6 - 24
- #OPTIMIZE language
- @new_settings << ['country-iso', nil, 'DE' ]
- @new_settings << ['language-iso', nil, 'de']
- @new_settings << ['date-format', nil, '0' ] # DD.MM.YYYY
- #OPTIMIZE ringtones
- @new_settings << ['ringer-melody', nil, '1']
-
- @new_settings << ['ringer-melody', nil, '2']
- @new_settings << ['ringer-tone-sequence', nil, '2']
-
- soft_keys = Array.new
- # Getting BLF keys only for the first level
- blf_keys = sip_account.softkeys.find(
- :all,
- :conditions => {:function => ['blf', 'conference']},
- :limit => blf_keys_max)
- #Getting other keys
- non_blf_keys = sip_account.softkeys.find(
- :all,
- :conditions => {:function => ['speed_dial']})
-
- # Fill softkey array with BLF keys up to shift key
- blf_keys.each do |k|
- soft_keys << k
- end
- # Fill sofkey with other keys up to end
- non_blf_keys.each do |k|
- if soft_keys.length < max_keys
- soft_keys << k
- end
- end
- # Delete unset softkeys
- while soft_keys.length < max_keys
- soft_keys << Softkey.new
- end
-
- key_pos=1
-
- #soft_keys.each do |sk|
-
- while key_pos < shift_key_position
-
- (1..shift_key_position-1).each do |key_idx|
- sk = soft_keys.shift
- logger.debug(sk.function, key_idx)
- if sk.function == "blf"
- @new_settings << ['function-key-def', key_idx, '59']
- @new_settings << ['select-dial', key_idx, sk.number ]
- elsif sk.function == "log_out"
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, 'f_lo' ]
- elsif sk.function == "log_in"
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, "f_li_#{sk.number}" ]
- elsif sk.function == "dtmf"
- @new_settings << ['function-key-def', key_idx, '54']
- @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ]
- elsif sk.function.nil?
- @new_settings << ['function-key-def', key_idx, '0']
- else
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, sk.number ]
- end
- @new_settings << ['key-label', key_idx, sk.label ]
- @new_settings << ['key-label-unicode', key_idx, sk.label ]
- key_pos = key_pos+1
-
- end
- end
- if key_pos == shift_key_position
- @new_settings << ['function-key-def', shift_key_position, '18']
- @new_settings << ['key-label', shift_key_position, 'Shift']
- @new_settings << ['key-label-unicode', shift_key_position, 'Shift']
- key_pos = key_pos+1
- end
-
- (1001..1000+shift_key_position-1).each do |key_idx|
- sk = soft_keys.shift
- if sk.function == "log_out"
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, 'f_lo' ]
- elsif sk.function == "log_in"
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, "f_li_#{sk.number}" ]
- elsif sk.function == "dtmf"
- @new_settings << ['function-key-def', key_idx, '54']
- @new_settings << ['stimulus-DTMF-sequence', key_idx, sk.number ]
- elsif sk.function.nil?
- @new_settings << ['function-key-def', key_idx, '0']
- else
- @new_settings << ['function-key-def', key_idx, '1']
- @new_settings << ['select-dial', key_idx, sk.number ]
- end
- @new_settings << ['key-label', key_idx, sk.label ]
- @new_settings << ['key-label-unicode', key_idx, sk.label ]
- key_pos = key_pos+1
-
- end
-
- #end
- logger.debug(@new_settings)
- end
-
- if @phone.nil? || sip_account.nil?
- respond_to { |format|
- format.xml { render :action => "clean-up" }
- }
-
- elsif (reply_status == 'accepted' && contact_reason == 'reply-to' && reply_action == 'ReadAllItems')
- respond_to { |format|
- format.xml { render :action => "write" }
- }
-
- elsif ["reply-to"].include? contact_reason
- respond_to { |format|
- format.xml { render :action => "clean-up" }
- }
-
- else
- respond_to { |format|
- format.xml { render :action => "index" }
- }
- end
-
- end
-end
diff --git a/app/controllers/config_snom_controller.rb b/app/controllers/config_snom_controller.rb
index 7542415..149e601 100644
--- a/app/controllers/config_snom_controller.rb
+++ b/app/controllers/config_snom_controller.rb
@@ -5,13 +5,13 @@ class ConfigSnomController < ApplicationController
KEY_REGEXP = {
'0' => "[ -.,_0]+",
'1' => "[ -.,_1]+",
- '2' => "[abc2]",
- '3' => "[def3]",
- '4' => "[ghi4]",
+ '2' => "[abc2\xC3\xA4]",
+ '3' => "[def3\xC3\xA9]",
+ '4' => "[ghi4\xC3\xAF]",
'5' => "[jkl5]",
- '6' => "[mno6]",
- '7' => "[pqrs7]",
- '8' => "[tuv8]",
+ '6' => "[mno6\xC3\xB6]",
+ '7' => "[pqrs7\xC3\x9F]",
+ '8' => "[tuv8\xC3\xBC]",
'9' => "[wxyz9]",
}
@@ -34,8 +34,8 @@ class ConfigSnomController < ApplicationController
@phone = Phone.where({ :mac_address => @mac_address }).first
end
- if ! @phone && PROVISIONING_AUTO_ADD_PHONE
- tenant = Tenant.where(:id => PROVISIONING_AUTO_TENANT_ID).first
+ if ! @phone && GsParameter.get('PROVISIONING_AUTO_ADD_PHONE')
+ tenant = Tenant.where(:id => GsParameter.get('PROVISIONING_AUTO_TENANT_ID')).first
if ! tenant
render(
:status => 404,
@@ -80,7 +80,7 @@ class ConfigSnomController < ApplicationController
'00041345' => 'Snom 821',
'00041348' => 'Snom 821',
'00041341' => 'Snom 870',
- '00041332' => 'snom MeetingPoint',
+ '00041332' => 'Snom meetingPoint',
}
@phone.phone_model = PhoneModel.where(:name => mac_address_to_model[@mac_address[0, 8]]).first
@@ -94,12 +94,12 @@ class ConfigSnomController < ApplicationController
return
end
- if ! PROVISIONING_AUTO_ADD_SIP_ACCOUNT
+ if ! GsParameter.get('PROVISIONING_AUTO_ADD_SIP_ACCOUNT')
return
end
caller_name_index = 0
- sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}%").sort { |item1, item2|
+ sip_account_last = tenant.sip_accounts.where('caller_name LIKE ?', "#{GsParameter.get('PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX')}%").sort { |item1, item2|
item1.caller_name.gsub(/[^0-9]/, '').to_i <=> item2.caller_name.gsub(/[^0-9]/, '').to_i
}.last
@@ -109,18 +109,18 @@ class ConfigSnomController < ApplicationController
caller_name_index = caller_name_index + 1
@sip_account = tenant.sip_accounts.build
- @sip_account.caller_name = "#{PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX}#{caller_name_index}"
- @sip_account.call_waiting = CALL_WAITING
- @sip_account.clir = DEFAULT_CLIR_SETTING
- @sip_account.clip = DEFAULT_CLIP_SETTING
+ @sip_account.caller_name = "#{GsParameter.get('PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX')}#{caller_name_index}"
+ @sip_account.call_waiting = GsParameter.get('CALL_WAITING')
+ @sip_account.clir = GsParameter.get('DEFAULT_CLIR_SETTING')
+ @sip_account.clip = GsParameter.get('DEFAULT_CLIP_SETTING')
@sip_account.voicemail_pin = random_pin
- @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT
+ @sip_account.callforward_rules_act_per_sip_account = GsParameter.get('CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT')
@sip_account.hotdeskable = false
loop do
- @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME)
+ @sip_account.auth_name = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_AUTH_NAME'))
break unless SipAccount.exists?(:auth_name => @sip_account.auth_name)
end
- @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD)
+ @sip_account.password = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_PASSWORD'))
if ! @sip_account.save
render(
@@ -182,9 +182,9 @@ class ConfigSnomController < ApplicationController
send_sensitve = @provisioning_authenticated || !@phone.provisioning_key_active
@phone_settings = Hash.new()
- if defined?(PROVISIONING_KEY_LENGTH) && PROVISIONING_KEY_LENGTH > 0
+ if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0
if @phone.provisioning_key.blank?
- @phone.update_attributes({ :provisioning_key => SecureRandom.hex(PROVISIONING_KEY_LENGTH), :provisioning_key_active => false })
+ @phone.update_attributes({ :provisioning_key => SecureRandom.hex(GsParameter.get('PROVISIONING_KEY_LENGTH')), :provisioning_key_active => false })
elsif @provisioning_authenticated
@phone.update_attributes({ :provisioning_key_active => true })
end
@@ -199,19 +199,19 @@ class ConfigSnomController < ApplicationController
end
end
- if defined?(PROVISIONING_SET_HTTP_USER) && @phone.http_user.blank?
- if PROVISIONING_SET_HTTP_USER.class == Fixnum
- @phone.update_attributes({ :http_user => SecureRandom.hex(PROVISIONING_SET_HTTP_USER) })
- elsif PROVISIONING_SET_HTTP_USER.class == String
- @phone.update_attributes({ :http_user => PROVISIONING_SET_HTTP_USER })
+ if !GsParameter.get('PROVISIONING_SET_HTTP_USER').nil? && @phone.http_user.blank?
+ if GsParameter.get('PROVISIONING_SET_HTTP_USER').class == Fixnum
+ @phone.update_attributes({ :http_user => SecureRandom.hex(GsParameter.get('PROVISIONING_SET_HTTP_USER')) })
+ elsif GsParameter.get('PROVISIONING_SET_HTTP_USER').class == String
+ @phone.update_attributes({ :http_user => GsParameter.get('PROVISIONING_SET_HTTP_USER') })
end
end
- if defined?(PROVISIONING_SET_HTTP_PASSWORD) && @phone.http_password.blank?
- if PROVISIONING_SET_HTTP_PASSWORD.class == Fixnum
- @phone.update_attributes({ :http_password => SecureRandom.hex(PROVISIONING_SET_HTTP_PASSWORD) })
- elsif PROVISIONING_SET_HTTP_PASSWORD.class == String
- @phone.update_attributes({ :http_password => PROVISIONING_SET_HTTP_PASSWORD })
+ if !GsParameter.get('PROVISIONING_SET_HTTP_PASSWORD').nil? && @phone.http_password.blank?
+ if GsParameter.get('PROVISIONING_SET_HTTP_PASSWORD').class == Fixnum
+ @phone.update_attributes({ :http_password => SecureRandom.hex(GsParameter.get('PROVISIONING_SET_HTTP_PASSWORD')) })
+ elsif GsParameter.get('PROVISIONING_SET_HTTP_PASSWORD').class == String
+ @phone.update_attributes({ :http_password => GsParameter.get('PROVISIONING_SET_HTTP_PASSWORD') })
end
end
@@ -503,6 +503,11 @@ class ConfigSnomController < ApplicationController
:idle_down => "keyevent F_NEXT_ID",
:idle_left => "url #{xml_applications_url}/call_history.xml?type=received",
:idle_right => "url #{xml_applications_url}/call_history.xml?type=missed",
+ :touch_idle_adr_book => "url #{xml_applications_url}/phone_book.xml",
+ :touch_idle_list_missed => "url #{xml_applications_url}/call_history.xml?type=missed",
+ :touch_idle_list_taken => "url #{xml_applications_url}/call_history.xml?type=received",
+ :touch_idle_redial => "url #{xml_applications_url}/call_history.xml?type=dialed",
+ :touch_idle_dialog => "url #{xml_applications_url}/call_history.xml",
}
# Remap conference key to first conference if found
diff --git a/app/controllers/fax_accounts_controller.rb b/app/controllers/fax_accounts_controller.rb
index ce03bc5..031080e 100644
--- a/app/controllers/fax_accounts_controller.rb
+++ b/app/controllers/fax_accounts_controller.rb
@@ -15,8 +15,8 @@ class FaxAccountsController < ApplicationController
def new
@fax_account = @parent.fax_accounts.build
@fax_account.name = generate_a_new_name(@parent, @fax_account)
- @fax_account.days_till_auto_delete = DAYS_TILL_AUTO_DELETE
- @fax_account.retries = DEFAULT_NUMBER_OF_RETRIES
+ @fax_account.days_till_auto_delete = GsParameter.get('DAYS_TILL_AUTO_DELETE')
+ @fax_account.retries = GsParameter.get('DEFAULT_NUMBER_OF_RETRIES')
@fax_account.station_id = @parent.to_s
@fax_account.phone_numbers.build
if @parent.class == User && !@parent.email.blank?
diff --git a/app/controllers/gateway_parameters_controller.rb b/app/controllers/gateway_parameters_controller.rb
new file mode 100644
index 0000000..d5ade9e
--- /dev/null
+++ b/app/controllers/gateway_parameters_controller.rb
@@ -0,0 +1,44 @@
+class GatewayParametersController < ApplicationController
+ load_and_authorize_resource :gateway
+ load_and_authorize_resource :gateway_parameter, :through => [:gateway]
+
+ def index
+ @gateway_parameters = @gateway.gateway_parameters
+ end
+
+ def show
+ @gateway_parameter = @gateway.gateway_parameters.find(params[:id])
+ end
+
+ def new
+ @gateway_parameter = @gateway.gateway_parameters.build
+ end
+
+ def create
+ @gateway_parameter = @gateway.gateway_parameters.build(params[:gateway_parameter])
+ if @gateway_parameter.save
+ redirect_to @gateway, :notice => t('gateway_parameters.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @gateway_parameter = @gateway.gateway_parameters.find(params[:id])
+ end
+
+ def update
+ @gateway_parameter = @gateway.gateway_parameters.find(params[:id])
+ if @gateway_parameter.update_attributes(params[:gateway_parameter])
+ redirect_to @gateway, :notice => t('gateway_parameters.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @gateway_parameter = @gateway.gateway_parameters.find(params[:id])
+ @gateway_parameter.destroy
+ redirect_to gateway_path(@gateway), :notice => t('gateway_parameters.controller.successfuly_destroyed')
+ end
+end
diff --git a/app/controllers/gateway_settings_controller.rb b/app/controllers/gateway_settings_controller.rb
new file mode 100644
index 0000000..0304411
--- /dev/null
+++ b/app/controllers/gateway_settings_controller.rb
@@ -0,0 +1,44 @@
+class GatewaySettingsController < ApplicationController
+ load_and_authorize_resource :gateway
+ load_and_authorize_resource :gateway_setting, :through => [:gateway]
+
+ def index
+ @gateway_settings = @gateway.gateway_settings
+ end
+
+ def show
+ end
+
+ def new
+ # @gateway_setting = @gateway.gateway_settings.build
+ end
+
+ def create
+ @gateway_setting = @gateway.gateway_settings.build(params[:gateway_setting])
+ @gateway_setting.class_type = GatewaySetting::GATEWAY_SETTINGS[@gateway.technology][@gateway_setting.name]
+ if @gateway_setting.save
+ redirect_to @gateway, :notice => t('gateway_settings.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @gateway_setting = @gateway.gateway_settings.find(params[:id])
+ end
+
+ def update
+ @gateway_setting = @gateway.gateway_settings.find(params[:id])
+ if @gateway_setting.update_attributes(params[:gateway_setting])
+ redirect_to @gateway, :notice => t('gateway_settings.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @gateway_setting = @gateway.gateway_settings.find(params[:id])
+ @gateway_setting.destroy
+ redirect_to gateway_path(@gateway), :notice => t('gateway_settings.controller.successfuly_destroyed')
+ end
+end
diff --git a/app/controllers/gateways_controller.rb b/app/controllers/gateways_controller.rb
new file mode 100644
index 0000000..5741195
--- /dev/null
+++ b/app/controllers/gateways_controller.rb
@@ -0,0 +1,57 @@
+class GatewaysController < ApplicationController
+ authorize_resource :gateway
+
+ def index
+ @gateways = Gateway.all
+ spread_breadcrumbs
+ end
+
+ def show
+ @gateway = Gateway.find(params[:id])
+ spread_breadcrumbs
+ end
+
+ def new
+ @gateway = Gateway.new
+ spread_breadcrumbs
+ end
+
+ def create
+ @gateway = Gateway.new(params[:gateway])
+ spread_breadcrumbs
+ if @gateway.save
+ redirect_to @gateway, :notice => t('gateways.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @gateway = Gateway.find(params[:id])
+ spread_breadcrumbs
+ end
+
+ def update
+ @gateway = Gateway.find(params[:id])
+ spread_breadcrumbs
+ if @gateway.update_attributes(params[:gateway])
+ redirect_to @gateway, :notice => t('gateways.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @gateway = Gateway.find(params[:id])
+ @gateway.destroy
+ redirect_to gateways_url, :notice => t('gateways.controller.successfuly_destroyed')
+ end
+
+ private
+ def spread_breadcrumbs
+ add_breadcrumb t("gateways.index.page_title"), gateways_path
+ if @gateway && !@gateway.new_record?
+ add_breadcrumb @gateway, @gateway
+ end
+ end
+end
diff --git a/app/controllers/gemeinschaft_setups_controller.rb b/app/controllers/gemeinschaft_setups_controller.rb
index e871862..347e043 100644
--- a/app/controllers/gemeinschaft_setups_controller.rb
+++ b/app/controllers/gemeinschaft_setups_controller.rb
@@ -1,8 +1,12 @@
class GemeinschaftSetupsController < ApplicationController
+ # We use the heater rake task to generate this file.
+ # So it loads super fast even on slow machines.
+ #
+ caches_page :new, :gzip => :best_compression
+
load_and_authorize_resource :gemeinschaft_setup
skip_before_filter :go_to_setup_if_new_installation
- # before_filter :redirect_if_not_a_fresh_installation
def new
@user = @gemeinschaft_setup.build_user(
@@ -21,7 +25,7 @@ class GemeinschaftSetupsController < ApplicationController
def create
if @gemeinschaft_setup.save
super_tenant = Tenant.create(
- :name => SUPER_TENANT_NAME,
+ :name => GsParameter.get('SUPER_TENANT_NAME'),
:country_id => @gemeinschaft_setup.country.id,
:language_id => @gemeinschaft_setup.language_id,
:description => t('gemeinschaft_setups.initial_setup.super_tenant_description'),
@@ -41,6 +45,25 @@ class GemeinschaftSetupsController < ApplicationController
super_tenant_super_admin_group = super_tenant.user_groups.create(:name => t('gemeinschaft_setups.initial_setup.super_admin_group_name'))
super_tenant_super_admin_group.user_group_memberships.create(:user_id => user.id)
+ # Set CallRoute defaults
+ CallRoute.factory_defaults_prerouting(@gemeinschaft_setup.country.country_code,
+ @gemeinschaft_setup.country.trunk_prefix,
+ @gemeinschaft_setup.country.international_call_prefix,
+ '',
+ @gemeinschaft_setup.default_area_code
+ )
+
+ # Set a couple of URLs in the GsParameter table
+ GsParameter.where(:name => 'phone_book_entry_image_url').first.update_attributes(:value => "http://#{@gemeinschaft_setup.sip_domain.host}/uploads/phone_book_entry/image")
+ GsParameter.where(:name => 'ringtone_url').first.update_attributes(:value => "http://#{@gemeinschaft_setup.sip_domain.host}")
+ GsParameter.where(:name => 'user_image_url').first.update_attributes(:value => "http://#{@gemeinschaft_setup.sip_domain.host}/uploads/user/image")
+
+ # Restart FreeSWITCH
+ if Rails.env.production?
+ require 'freeswitch_event'
+ FreeswitchAPI.execute('fsctl', 'shutdown restart')
+ end
+
# Auto-Login:
session[:user_id] = user.id
@@ -51,16 +74,4 @@ class GemeinschaftSetupsController < ApplicationController
end
end
- private
-
- def redirect_if_not_a_fresh_installation
- if GemeinschaftSetup.all.count > 0
- if current_user
- redirect_to root_url , :alert => t('gemeinschaft_setups.initial_setup.access_denied_only_available_on_a_new_system')
- else
- redirect_to log_in_path , :alert => t('gemeinschaft_setups.initial_setup.access_denied_only_available_on_a_new_system')
- end
- end
- end
-
end
diff --git a/app/controllers/gs_nodes_controller.rb b/app/controllers/gs_nodes_controller.rb
index 3667775..17c9e8b 100644
--- a/app/controllers/gs_nodes_controller.rb
+++ b/app/controllers/gs_nodes_controller.rb
@@ -70,7 +70,7 @@ class GsNodesController < ApplicationController
@request_class = '';
end
- @node = GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS).first
+ @node = GsNode.where(:ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS')).first
if @request_class.blank? || @request_class == "tenants"
@tenants = Tenant.where('updated_at > ?', @newer_as)
diff --git a/app/controllers/gs_parameters_controller.rb b/app/controllers/gs_parameters_controller.rb
new file mode 100644
index 0000000..bd8b44b
--- /dev/null
+++ b/app/controllers/gs_parameters_controller.rb
@@ -0,0 +1,44 @@
+class GsParametersController < ApplicationController
+ load_and_authorize_resource :gs_parameter
+
+ before_filter :spread_breadcrumbs
+
+ def index
+ @gs_parameters_unordered = GsParameter.scoped
+ @gs_parameters = GsParameter.order([:section, :name])
+ @sections = @gs_parameters.pluck(:section).uniq.sort
+ end
+
+ def show
+ @gs_parameter = GsParameter.find(params[:id])
+ end
+
+ def new
+ @gs_parameter = GsParameter.new
+ end
+
+ def edit
+ @gs_parameter = GsParameter.find(params[:id])
+ end
+
+ def update
+ @gs_parameter = GsParameter.find(params[:id])
+ if @gs_parameter.update_attributes(gs_parameter_params)
+ redirect_to @gs_parameter, :notice => t('gs_parameters.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ private
+ def gs_parameter_params
+ params.require(:gs_parameter).permit(:value, :class_type, :description)
+ end
+
+ def spread_breadcrumbs
+ add_breadcrumb t("gs_parameters.index.page_title"), gs_parameters_path
+ if @gs_parameter && !@gs_parameter.new_record?
+ add_breadcrumb @gs_parameter, gs_parameter_path(@gs_parameter)
+ end
+ end
+end
diff --git a/app/controllers/gui_functions_controller.rb b/app/controllers/gui_functions_controller.rb
index 2ab2c5e..0cb7898 100644
--- a/app/controllers/gui_functions_controller.rb
+++ b/app/controllers/gui_functions_controller.rb
@@ -1,4 +1,6 @@
class GuiFunctionsController < ApplicationController
+ load_resource :gui_function
+
before_filter :load_user_groups
before_filter :spread_breadcrumbs
@@ -60,14 +62,10 @@ class GuiFunctionsController < ApplicationController
end
def spread_breadcrumbs
- if @tenant
- add_breadcrumb t("user_groups.index.page_title"), tenant_user_groups_path(@tenant)
- if @user_group && !@user_group.new_record?
- add_breadcrumb @user_group, tenant_user_group_path(@tenant, @user_group)
- end
- end
-
add_breadcrumb t("gui_functions.index.page_title"), gui_functions_path
+ if @gui_function && !@gui_function.new_record?
+ add_breadcrumb @gui_function, gui_function_path(@gui_function)
+ end
end
end
diff --git a/app/controllers/page_controller.rb b/app/controllers/page_controller.rb
index 4ea4d25..dc5f57b 100644
--- a/app/controllers/page_controller.rb
+++ b/app/controllers/page_controller.rb
@@ -5,7 +5,12 @@ class PageController < ApplicationController
before_filter :if_fresh_system_then_go_to_wizard
skip_before_filter :home_breadcrumb, :only => [:index]
- def index;end
+ def index
+ if current_user
+ redirect_to [current_user.current_tenant, current_user]
+ end
+ end
+
def conference;end
def beginners_intro;end
diff --git a/app/controllers/phone_book_entries_controller.rb b/app/controllers/phone_book_entries_controller.rb
index 823d50e..9cc9f18 100644
--- a/app/controllers/phone_book_entries_controller.rb
+++ b/app/controllers/phone_book_entries_controller.rb
@@ -71,7 +71,7 @@ class PhoneBookEntriesController < ApplicationController
order([ :last_name, :first_name, :organization ]).
paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
end
diff --git a/app/controllers/phone_books_controller.rb b/app/controllers/phone_books_controller.rb
index 54e7889..5f2d61f 100644
--- a/app/controllers/phone_books_controller.rb
+++ b/app/controllers/phone_books_controller.rb
@@ -22,7 +22,7 @@ class PhoneBooksController < ApplicationController
order([ :last_name, :first_name ]).
paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
else
# search by name
@@ -39,7 +39,7 @@ class PhoneBooksController < ApplicationController
order([ :last_name, :first_name ]).
paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
end
end
diff --git a/app/controllers/phone_numbers_controller.rb b/app/controllers/phone_numbers_controller.rb
index 065934c..c562954 100644
--- a/app/controllers/phone_numbers_controller.rb
+++ b/app/controllers/phone_numbers_controller.rb
@@ -77,6 +77,23 @@ class PhoneNumbersController < ApplicationController
redirect_to :back
end
+ def call
+ sip_account = nil
+ current_user.sip_accounts.each do |user_sip_account|
+ if user_sip_account.registration
+ sip_account = user_sip_account
+ break
+ end
+ end
+
+ if can?(:call, @phone_number) && sip_account
+ if ! @phone_number.number.blank?
+ sip_account.call(@phone_number.number)
+ end
+ end
+ redirect_to(:back)
+ end
+
private
def set_and_authorize_parent
@parent = @phone_book_entry || @sip_account || @conference || @fax_account ||
diff --git a/app/controllers/phones_controller.rb b/app/controllers/phones_controller.rb
index 2698465..3672390 100644
--- a/app/controllers/phones_controller.rb
+++ b/app/controllers/phones_controller.rb
@@ -46,6 +46,7 @@ class PhonesController < ApplicationController
m = method( :"#{@phoneable.class.name.underscore}_phone_path" )
redirect_to m.( @phoneable, @phone ), :notice => t('phones.controller.successfuly_updated')
else
+ set_fallback_sip_accounts
render :edit
end
end
@@ -78,11 +79,11 @@ class PhonesController < ApplicationController
end
def set_fallback_sip_accounts
- used_sip_account_ids = Phone.where(:fallback_sip_account_id => SipAccount.pluck(:id)).pluck(:fallback_sip_account_id)
- @fallback_sip_accounts = SipAccount.where(:sip_accountable_type => 'Tenant').where(:hotdeskable => true) - SipAccount.where(:id => used_sip_account_ids)
- if @phone && !@phone.fallback_sip_account_id.blank? && SipAccount.exists?(@phone.fallback_sip_account_id)
- @fallback_sip_accounts << SipAccount.where(:id => @phone.fallback_sip_account_id).first
+ used_sip_account_ids = Phone.pluck(:fallback_sip_account_id) + PhoneSipAccount.pluck(:sip_account_id)
+ if @phone
+ used_sip_account_ids = used_sip_account_ids - [ @phone.fallback_sip_account_id ]
end
+ @fallback_sip_accounts = SipAccount.where(:sip_accountable_type => 'Tenant') - SipAccount.where(:id => used_sip_account_ids)
end
end
diff --git a/app/controllers/route_elements_controller.rb b/app/controllers/route_elements_controller.rb
new file mode 100644
index 0000000..c4e4c1a
--- /dev/null
+++ b/app/controllers/route_elements_controller.rb
@@ -0,0 +1,67 @@
+class RouteElementsController < ApplicationController
+ load_and_authorize_resource :call_route
+ load_and_authorize_resource :route_element, :through => [:call_route]
+
+ before_filter :spread_breadcrumbs
+
+ def index
+ @route_elements = @call_route.route_elements
+ end
+
+ def show
+ @route_element = @call_route.route_elements.find(params[:id])
+ end
+
+ def new
+ @route_element = @call_route.route_elements.build
+ end
+
+ def create
+ @route_element = @call_route.route_elements.build(params[:route_element])
+ if @route_element.save
+ redirect_to [@call_route, @route_element], :notice => t('route_elements.controller.successfuly_created')
+ else
+ render :new
+ end
+ end
+
+ def edit
+ @route_element = @call_route.route_elements.find(params[:id])
+ end
+
+ def update
+ @route_element = @call_route.route_elements.find(params[:id])
+ if @route_element.update_attributes(params[:route_element])
+ redirect_to [@call_route, @route_element], :notice => t('route_elements.controller.successfuly_updated')
+ else
+ render :edit
+ end
+ end
+
+ def destroy
+ @route_element = @call_route.route_elements.find(params[:id])
+ @route_element.destroy
+ redirect_to call_route_route_elements_path(@call_route), :notice => t('route_elements.controller.successfuly_destroyed')
+ end
+
+ def move_higher
+ @route_element.move_higher
+ redirect_to :back
+ end
+
+ def move_lower
+ @route_element.move_lower
+ redirect_to :back
+ end
+
+ private
+ def spread_breadcrumbs
+ add_breadcrumb t("call_routes.index.page_title"), call_routes_path
+ add_breadcrumb @call_route, call_route_path(@call_route)
+ add_breadcrumb t("route_elements.index.page_title"), call_route_route_elements_path(@call_route)
+ if @route_element && !@route_element.new_record?
+ add_breadcrumb @route_element, call_route_route_element_path(@call_route, @route_element)
+ end
+ end
+
+end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index f92ae1c..81b04e0 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -36,7 +36,7 @@ class SessionsController < ApplicationController
private
def redirect_to_https
- if GUI_REDIRECT_HTTPS and ! request.ssl?
+ if GsParameter.get('GUI_REDIRECT_HTTPS') and ! request.ssl?
redirect_to :protocol => "https://"
end
end
diff --git a/app/controllers/sip_accounts_controller.rb b/app/controllers/sip_accounts_controller.rb
index 1f3166e..a83208b 100644
--- a/app/controllers/sip_accounts_controller.rb
+++ b/app/controllers/sip_accounts_controller.rb
@@ -15,21 +15,23 @@ class SipAccountsController < ApplicationController
def new
@sip_account = @parent.sip_accounts.build
@sip_account.caller_name = @parent
- @sip_account.call_waiting = CALL_WAITING
- @sip_account.clir = DEFAULT_CLIR_SETTING
- @sip_account.clip = DEFAULT_CLIP_SETTING
+ @sip_account.call_waiting = GsParameter.get('CALL_WAITING')
+ @sip_account.clir = GsParameter.get('DEFAULT_CLIR_SETTING')
+ @sip_account.clip = GsParameter.get('DEFAULT_CLIP_SETTING')
@sip_account.voicemail_pin = random_pin
- @sip_account.callforward_rules_act_per_sip_account = CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT
- @sip_account.hotdeskable = true
+ @sip_account.callforward_rules_act_per_sip_account = GsParameter.get('CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT')
+ if @parent.class == User
+ @sip_account.hotdeskable = true
+ end
# Make sure that we don't use an already taken auth_name
#
loop do
- @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME)
+ @sip_account.auth_name = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_AUTH_NAME'))
break unless SipAccount.exists?(:auth_name => @sip_account.auth_name)
end
- @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD)
+ @sip_account.password = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_PASSWORD'))
end
def create
@@ -37,13 +39,13 @@ class SipAccountsController < ApplicationController
if @sip_account.auth_name.blank?
loop do
- @sip_account.auth_name = SecureRandom.hex(DEFAULT_LENGTH_SIP_AUTH_NAME)
+ @sip_account.auth_name = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_AUTH_NAME'))
break unless SipAccount.exists?(:auth_name => @sip_account.auth_name)
end
end
if @sip_account.password.blank?
- @sip_account.password = SecureRandom.hex(DEFAULT_LENGTH_SIP_PASSWORD)
+ @sip_account.password = SecureRandom.hex(GsParameter.get('DEFAULT_LENGTH_SIP_PASSWORD'))
end
if @sip_account.save
@@ -69,7 +71,7 @@ class SipAccountsController < ApplicationController
def destroy
@sip_account.destroy
m = method( :"#{@parent.class.name.underscore}_sip_accounts_url" )
- redirect_to m.( @parent ), :notice => t('sip_accounts.controller.successfuly_destroyed')
+ redirect_to :back, :notice => t('sip_accounts.controller.successfuly_destroyed')
end
private
diff --git a/app/controllers/tenants_controller.rb b/app/controllers/tenants_controller.rb
index 7bb8ecd..cb67e5f 100644
--- a/app/controllers/tenants_controller.rb
+++ b/app/controllers/tenants_controller.rb
@@ -1,13 +1,17 @@
class TenantsController < ApplicationController
- load_and_authorize_resource :tenant
+ authorize_resource :tenant
def index
+ @tenants = Tenant.scoped
end
def show
+ @tenant = Tenant.find(params[:id])
+ @gateways = Gateway.order(:updated_at)
end
def new
+ @tenant = Tenant.new
@tenant.name = generate_a_new_name(@tenant)
@tenant.sip_domain = SipDomain.last
@tenant.country = GemeinschaftSetup.first.country
@@ -18,6 +22,8 @@ class TenantsController < ApplicationController
end
def create
+ @tenant = Tenant.new(tenant_params)
+
if @tenant.save
# Become a member of this tenant.
#
@@ -86,10 +92,12 @@ class TenantsController < ApplicationController
end
def edit
+ @tenant = Tenant.find(params[:id])
end
def update
- if @tenant.update_attributes(params[:tenant])
+ @tenant = Tenant.find(params[:id])
+ if @tenant.update_attributes(tenant_params)
redirect_to @tenant, :notice => t('tenants.controller.successfuly_updated')
else
render :edit
@@ -97,8 +105,15 @@ class TenantsController < ApplicationController
end
def destroy
+ @tenant = Tenant.find(params[:id])
@tenant.destroy
redirect_to tenants_url, :notice => t('tenants.controller.successfuly_destroyed')
end
+
+ private
+ def tenant_params
+ params.require(:tenant).permit(:name, :description, :sip_domain_id, :country_id, :language_id, :from_field_pin_change_email, :from_field_voicemail_email
+)
+ end
end
diff --git a/app/controllers/trigger_controller.rb b/app/controllers/trigger_controller.rb
new file mode 100644
index 0000000..e9821f6
--- /dev/null
+++ b/app/controllers/trigger_controller.rb
@@ -0,0 +1,11 @@
+class TriggerController < ApplicationController
+ def voicemail
+ # Something is triggered when ever a local script fetches this action.
+ #
+ end
+
+ def fax
+ # Something is triggered when ever a local script fetches this action.
+ #
+ end
+end
diff --git a/app/controllers/user_groups_controller.rb b/app/controllers/user_groups_controller.rb
index ff3292c..9e08ff1 100644
--- a/app/controllers/user_groups_controller.rb
+++ b/app/controllers/user_groups_controller.rb
@@ -38,7 +38,7 @@ class UserGroupsController < ApplicationController
def destroy
@user_group.destroy
- redirect_to method( :"#{@parent.class.name.underscore}_user_groups_path" ).(@parent), :notice => t('user_groups.controller.successfuly_destroyed')
+ redirect_to :back, :notice => t('user_groups.controller.successfuly_destroyed')
end
private
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 454c26b..584d08c 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -10,7 +10,7 @@ class UsersController < ApplicationController
end
def show
- @phone_books = PhoneBook.accessible_by( Ability.new( @user ) ).all
+ @phone_books = PhoneBook.accessible_by( Ability.new( @user ), :read )
end
def new
@@ -52,7 +52,7 @@ class UsersController < ApplicationController
def destroy
@user.destroy
- redirect_to @parent, :notice => t('users.controller.successfuly_destroyed')
+ redirect_to :back, :notice => t('users.controller.successfuly_destroyed')
end
def destroy_avatar
diff --git a/app/controllers/voicemail_messages_controller.rb b/app/controllers/voicemail_messages_controller.rb
index 58f5265..dfe0ae4 100644
--- a/app/controllers/voicemail_messages_controller.rb
+++ b/app/controllers/voicemail_messages_controller.rb
@@ -24,17 +24,17 @@ class VoicemailMessagesController < ApplicationController
if @type == 'read'
@voicemail_messages = @sip_account.voicemail_messages.where('read_epoch > 0').order('created_epoch DESC').paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
elsif @type == 'unread'
@voicemail_messages = @sip_account.voicemail_messages.where(:read_epoch => 0).order('created_epoch DESC').paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
else
@voicemail_messages = @sip_account.voicemail_messages.order('created_epoch DESC').paginate(
:page => @pagination_page_number,
- :per_page => DEFAULT_PAGINATION_ENTRIES_PER_PAGE
+ :per_page => GsParameter.get('DEFAULT_PAGINATION_ENTRIES_PER_PAGE')
)
end
end
diff --git a/app/helpers/call_routes_helper.rb b/app/helpers/call_routes_helper.rb
new file mode 100644
index 0000000..dfe87dd
--- /dev/null
+++ b/app/helpers/call_routes_helper.rb
@@ -0,0 +1,2 @@
+module CallRoutesHelper
+end
diff --git a/app/helpers/gateway_parameters_helper.rb b/app/helpers/gateway_parameters_helper.rb
new file mode 100644
index 0000000..a6fa037
--- /dev/null
+++ b/app/helpers/gateway_parameters_helper.rb
@@ -0,0 +1,2 @@
+module GatewayParametersHelper
+end
diff --git a/app/helpers/gateway_settings_helper.rb b/app/helpers/gateway_settings_helper.rb
new file mode 100644
index 0000000..acb0a8c
--- /dev/null
+++ b/app/helpers/gateway_settings_helper.rb
@@ -0,0 +1,2 @@
+module GatewaySettingsHelper
+end
diff --git a/app/helpers/gateways_helper.rb b/app/helpers/gateways_helper.rb
new file mode 100644
index 0000000..247e4bc
--- /dev/null
+++ b/app/helpers/gateways_helper.rb
@@ -0,0 +1,2 @@
+module GatewaysHelper
+end
diff --git a/app/helpers/gs_parameters_helper.rb b/app/helpers/gs_parameters_helper.rb
new file mode 100644
index 0000000..ec339ea
--- /dev/null
+++ b/app/helpers/gs_parameters_helper.rb
@@ -0,0 +1,2 @@
+module GsParametersHelper
+end
diff --git a/app/helpers/route_elements_helper.rb b/app/helpers/route_elements_helper.rb
new file mode 100644
index 0000000..4262a50
--- /dev/null
+++ b/app/helpers/route_elements_helper.rb
@@ -0,0 +1,2 @@
+module RouteElementsHelper
+end
diff --git a/app/helpers/trigger_helper.rb b/app/helpers/trigger_helper.rb
new file mode 100644
index 0000000..0ababb3
--- /dev/null
+++ b/app/helpers/trigger_helper.rb
@@ -0,0 +1,2 @@
+module TriggerHelper
+end
diff --git a/app/mailers/notifications.rb b/app/mailers/notifications.rb
index 2c7f2ce..5b46f23 100644
--- a/app/mailers/notifications.rb
+++ b/app/mailers/notifications.rb
@@ -26,7 +26,7 @@ class Notifications < ActionMailer::Base
@pin[:pin] = conference.pin
@pin[:phone_numbers] = conference.phone_numbers.join(', ')
- mail(from: Tenant.find(DEFAULT_API_TENANT_ID).from_field_pin_change_email,to: "#{conference.conferenceable.email}", :subject => "Conference PIN changed: #{@pin[:conference]}")
+ mail(from: Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID')).from_field_pin_change_email,to: "#{conference.conferenceable.email}", :subject => "Conference PIN changed: #{@pin[:conference]}")
end
def new_password(user, password)
@@ -39,7 +39,7 @@ class Notifications < ActionMailer::Base
@message[:greeting] = user.user_name
end
- mail(from: Tenant.find(DEFAULT_API_TENANT_ID).from_field_pin_change_email, to: "#{user.email}", :subject => "Password recovery")
+ mail(from: Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID')).from_field_pin_change_email, to: "#{user.email}", :subject => "Password recovery")
end
def new_voicemail(freeswitch_voicemail_msg, attach_file = false)
@@ -67,7 +67,7 @@ class Notifications < ActionMailer::Base
attachments["#{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.strftime('%Y%m%d-%H%M%S')}-#{caller_number}.wav"] = File.read(freeswitch_voicemail_msg.file_path)
end
- mail(from: Tenant.find(DEFAULT_API_TENANT_ID).from_field_voicemail_email, to: "#{user.email}", :subject => "New Voicemail from #{@voicemail[:from]}, received #{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.to_s}")
+ mail(from: Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID')).from_field_voicemail_email, to: "#{user.email}", :subject => "New Voicemail from #{@voicemail[:from]}, received #{Time.at(freeswitch_voicemail_msg.created_epoch).getlocal.to_s}")
end
def new_fax(fax_document)
@@ -104,7 +104,7 @@ class Notifications < ActionMailer::Base
end
end
attachments["#{fax_document.created_at.strftime('%Y%m%d-%H%M%S')}-#{caller_number}.pdf"] = File.read(fax_document.document.path)
- mail(from: Tenant.find(DEFAULT_API_TENANT_ID).from_field_voicemail_email, to: "#{fax_account.email}", :subject => "New Fax Document from #{@fax[:from]}, received #{fax_document.created_at}")
+ mail(from: Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID')).from_field_voicemail_email, to: "#{fax_account.email}", :subject => "New Fax Document from #{@fax[:from]}, received #{fax_document.created_at}")
end
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index d9ec74a..b846af0 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -27,6 +27,10 @@ class Ability
#
cannot [:create, :destroy, :edit, :update], Tenant, :id => 1
+ # Can't destroy any tenant
+ #
+ cannot :destroy, Tenant
+
cannot :manage, PhoneBook
# Phonebooks and PhoneBookEntries
@@ -70,9 +74,14 @@ class Ability
# Dirty hack to disable PhoneNumberRange in the GUI
#
- if STRICT_INTERNAL_EXTENSION_HANDLING == false
+ if GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') == false
cannot :manage, PhoneNumberRange
end
+
+ # GsParameter and GuiFunction can't be created or deleted via the GUI
+ #
+ cannot [:create, :destroy], GsParameter
+ cannot [:create, :destroy], GuiFunction
else
# Any user can do the following stuff.
#
diff --git a/app/models/access_authorization.rb b/app/models/access_authorization.rb
index ef33115..878799a 100644
--- a/app/models/access_authorization.rb
+++ b/app/models/access_authorization.rb
@@ -18,7 +18,9 @@ class AccessAuthorization < ActiveRecord::Base
:allow_nil => true, :allow_blank => true,
:message => "must be numeric."
- validates_length_of :pin, :minimum => MINIMUM_PIN_LENGTH, :maximum => MAXIMUM_PIN_LENGTH,
+ validates_length_of :pin,
+ :minimum => (GsParameter.get('MINIMUM_PIN_LENGTH').nil? ? 4 : GsParameter.get('MINIMUM_PIN_LENGTH')),
+ :maximum => (GsParameter.get('MAXIMUM_PIN_LENGTH').nil? ? 10 : GsParameter.get('MAXIMUM_PIN_LENGTH')),
:allow_nil => true, :allow_blank => true
has_many :phone_numbers, :as => :phone_numberable, :dependent => :destroy
diff --git a/app/models/api/row.rb b/app/models/api/row.rb
index ac35516..e82a3e2 100644
--- a/app/models/api/row.rb
+++ b/app/models/api/row.rb
@@ -28,7 +28,7 @@ class Api::Row < ActiveRecord::Base
end
def create_a_new_gemeinschaft_user
- tenant = Tenant.find(DEFAULT_API_TENANT_ID)
+ tenant = Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID'))
# Find or create the user
#
diff --git a/app/models/automatic_call_distributor.rb b/app/models/automatic_call_distributor.rb
index cd887d5..5807757 100644
--- a/app/models/automatic_call_distributor.rb
+++ b/app/models/automatic_call_distributor.rb
@@ -1,7 +1,7 @@
class AutomaticCallDistributor < ActiveRecord::Base
attr_accessible :uuid, :name, :strategy, :automatic_call_distributorable_type, :automatic_call_distributorable_id, :max_callers, :agent_timeout, :retry_timeout, :join, :leave, :gs_node_id, :announce_position, :announce_call_agents, :greeting, :goodbye, :music
- belongs_to :automatic_call_distributorable, :polymorphic => true
+ belongs_to :automatic_call_distributorable, :polymorphic => true, :touch => true
has_many :acd_agents, :dependent => :destroy
has_many :phone_numbers, :as => :phone_numberable, :dependent => :destroy
@@ -26,6 +26,6 @@ class AutomaticCallDistributor < ActiveRecord::Base
self.announce_call_agents ||= 'ivr/ivr-stay_on_line_call_answered_momentarily.wav'
self.greeting ||= 'ivr/ivr-thank_you_for_calling.wav'
self.goodbye ||= 'ivr/ivr-thank_you_for_calling.wav'
- self.music ||= 'local_stream://mohl'
+ self.music ||= 'local_stream://moh'
end
end
diff --git a/app/models/call_forward.rb b/app/models/call_forward.rb
index 0018cfb..8a8d1df 100644
--- a/app/models/call_forward.rb
+++ b/app/models/call_forward.rb
@@ -28,7 +28,7 @@ class CallForward < ActiveRecord::Base
validates_numericality_of :depth,
:only_integer => true,
:greater_than_or_equal_to => 1,
- :less_than_or_equal_to => MAX_CALL_FORWARD_DEPTH
+ :less_than_or_equal_to => (GsParameter.get('MAX_CALL_FORWARD_DEPTH').nil? ? 0 : GsParameter.get('MAX_CALL_FORWARD_DEPTH'))
before_validation {
self.timeout = nil if self.call_forward_case_id != 3
diff --git a/app/models/call_route.rb b/app/models/call_route.rb
new file mode 100644
index 0000000..28120c1
--- /dev/null
+++ b/app/models/call_route.rb
@@ -0,0 +1,241 @@
+class CallRoute < ActiveRecord::Base
+ # https://github.com/rails/strong_parameters
+ include ActiveModel::ForbiddenAttributesProtection
+
+ ROUTING_TABLES = ['prerouting', 'outbound', 'inbound']
+
+ has_many :route_elements, :dependent => :destroy
+
+ validates :name,
+ :presence => true
+
+ validates :routing_table,
+ :presence => true,
+ :inclusion => { :in => ROUTING_TABLES }
+
+ acts_as_list :scope => '`routing_table` = \'#{routing_table}\''
+
+ def to_s
+ name.to_s
+ end
+
+ def move_up?
+ return self.position.to_i > CallRoute.where(:routing_table => self.routing_table ).order(:position).first.position.to_i
+ end
+
+ def move_down?
+ return self.position.to_i < CallRoute.where(:routing_table => self.routing_table ).order(:position).last.position.to_i
+ end
+
+ def self.factory_defaults_prerouting(country_code, national_prefix = '', international_prefix = '', trunk_access_code = '', area_code = '')
+ CallRoute.where(:routing_table => "prerouting").destroy_all
+
+ CallRoute.create_prerouting_entry('international call', [
+ { :pattern => '^'+trunk_access_code+international_prefix+'([1-9]%d+)$', :replacement => '+%1', },
+ ], 'phonenumber')
+
+ CallRoute.create_prerouting_entry('national call', [
+ { :pattern => '^'+trunk_access_code+national_prefix+'([1-9]%d+)$', :replacement => '+'+country_code+'%1', },
+ ], 'phonenumber')
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ CallRoute.create_prerouting_entry('local call', [
+ { :pattern => '^'+trunk_access_code+'([1-9]%d+)$', :replacement => '+'+country_code+area_code+'%1', },
+ ], 'phonenumber')
+ end
+
+ CallRoute.create_prerouting_entry('log in', [
+ { :pattern => '^%*0%*$', :replacement => 'f-li', },
+ { :pattern => '^%*0%*(%+?%d+)#*$', :replacement => 'f-li-%1', },
+ { :pattern => '^%*0%*(%+?%d+)%*(%d+)#*$', :replacement => 'f-li-%1-%2', },
+ ])
+
+ CallRoute.create_prerouting_entry('log out', [
+ { :pattern => '^#0#$', :replacement => 'f-lo', },
+ ])
+
+ CallRoute.create_prerouting_entry('toggle ACD membership', [
+ { :pattern => '^%*5%*(%+?%d+)#$', :replacement => 'f-acdmtg-0-%1', },
+ ])
+
+ CallRoute.create_prerouting_entry('activate CLIP', [
+ { :pattern => '^%*30#$', :replacement => 'f-clipon', },
+ ])
+
+ CallRoute.create_prerouting_entry('deactivate CLIP', [
+ { :pattern => '^#30#$', :replacement => 'f-clipoff', },
+ ])
+
+ CallRoute.create_prerouting_entry('activate CLIR', [
+ { :pattern => '^#31#$', :replacement => 'f-cliron', },
+ ])
+
+ CallRoute.create_prerouting_entry('deactivate CLIR', [
+ { :pattern => '^%*31#$', :replacement => 'f-cliroff', },
+ ])
+
+ elements = [
+ { :pattern => '^#31#(%+?[1-9]%d+)$', :replacement => 'f-dcliron-%1', },
+ { :pattern => '^#31#'+trunk_access_code+international_prefix+'([1-9]%d+)$', :replacement => 'f-dcliron-+%1' },
+ { :pattern => '^#31#'+trunk_access_code+national_prefix+'([1-9]%d+)$', :replacement => 'f-dcliron-+'+country_code+'%1' },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^#31#'+trunk_access_code+'([1-9]%d+)$', :replacement => 'f-dcliron-+'+country_code+area_code+'%1' }
+ end
+
+ CallRoute.create_prerouting_entry('activate CLIR for call', elements)
+
+ elements = [
+ { :pattern => '^%*31#(%+?[1-9]%d+)$', :replacement => 'f-dcliroff-%1', },
+ { :pattern => '^%*31#'+trunk_access_code+international_prefix+'([1-9]%d+)$', :replacement => 'f-dcliroff-+%1' },
+ { :pattern => '^%*31#'+trunk_access_code+national_prefix+'([1-9]%d+)$', :replacement => 'f-dcliroff-+'+country_code+'%1' },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^%*31#'+trunk_access_code+'([1-9]%d+)$', :replacement => 'f-dcliroff-+'+country_code+area_code+'%1' }
+ end
+
+ CallRoute.create_prerouting_entry('deactivate CLIR for call', elements)
+
+ CallRoute.create_prerouting_entry('activate call waiting', [
+ { :pattern => '^%*43#$', :replacement => 'f-cwaon', },
+ ])
+
+ CallRoute.create_prerouting_entry('deactivate call waiting', [
+ { :pattern => '^#43#$', :replacement => 'f-cwaoff', },
+ ])
+
+ CallRoute.create_prerouting_entry('deactivate all call forwards', [
+ { :pattern => '^#002#$', :replacement => 'f-cfoff', },
+ ])
+
+ CallRoute.create_prerouting_entry('delete all call forwards', [
+ { :pattern => '^##002#$', :replacement => 'f-cfdel', },
+ ])
+
+ elements = [
+ { :pattern => '^%*21#$', :replacement => 'f-cfu', },
+ { :pattern => '^%*%*?21%*(%+?[1-9]%d+)#$', :replacement => 'f-cfu-%1', },
+ { :pattern => '^%*%*?21%*'+trunk_access_code+international_prefix+'([1-9]%d+)#$', :replacement => 'f-cfu-+%1', },
+ { :pattern => '^%*%*?21%*'+trunk_access_code+national_prefix+'([1-9]%d+)#$', :replacement => 'f-cfu-+'+country_code+'%1', },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^%*%*?21%*'+trunk_access_code+'([1-9]%d+)#$', :replacement => 'f-cfu-+'+country_code+area_code+'%1' }
+ end
+
+ CallRoute.create_prerouting_entry('set unconditional call forwarding', elements)
+
+ CallRoute.create_prerouting_entry('deactivate unconditional call forwarding', [
+ { :pattern => '^#21#$', :replacement => 'f-cfuoff', },
+ ])
+
+ CallRoute.create_prerouting_entry('delete unconditional call forwarding', [
+ { :pattern => '^##21#$', :replacement => 'f-cfudel', },
+ ])
+
+ elements = [
+ { :pattern => '^%*61#$', :replacement => 'f-cfn', },
+ { :pattern => '^%*%*?61%*'+trunk_access_code+international_prefix+'([1-9]%d+)#$', :replacement => 'f-cfn-+%1', },
+ { :pattern => '^%*%*?61%*'+trunk_access_code+national_prefix+'([1-9]%d+)#$', :replacement => 'f-cfn-+'+country_code+'%1', },
+ { :pattern => '^%*%*?61%*(%+?[1-9]%d+)#$', :replacement => 'f-cfn-%1', },
+ { :pattern => '^%*%*?61%*'+trunk_access_code+international_prefix+'([1-9]%d+)%*(%d+)#$', :replacement => 'f-cfn-+%1-%2', },
+ { :pattern => '^%*%*?61%*'+trunk_access_code+national_prefix+'([1-9]%d+)%*(%d+)#$', :replacement => 'f-cfn-+'+country_code+'%1-%2', },
+ { :pattern => '^%*%*?61%*(%+?[1-9]%d+)%*(%d+)#$', :replacement => 'f-cfn-%1-%2', },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^%*%*?61%*'+trunk_access_code+'([1-9]%d+)#$', :replacement => 'f-cfn-+'+country_code+area_code+'%1' }
+ elements << { :pattern => '^%*%*?61%*'+trunk_access_code+'([1-9]%d+)%*(%d+)#$', :replacement => 'f-cfn-+'+country_code+area_code+'%1-%2' }
+ end
+
+ CallRoute.create_prerouting_entry('call forward if not answered', elements)
+
+ CallRoute.create_prerouting_entry('deactivate call forward if not answered', [
+ { :pattern => '^#61#$', :replacement => 'f-cfnoff', },
+ ])
+
+ CallRoute.create_prerouting_entry('delete call forward if not answered', [
+ { :pattern => '^##61#$', :replacement => 'f-cfndel', },
+ ])
+
+ elements = [
+ { :pattern => '^%*62#$', :replacement => 'f-cfo', },
+ { :pattern => '^%*%*?62%*(%+?[1-9]%d+)#$', :replacement => 'f-cfo-%1', },
+ { :pattern => '^%*%*?62%*'+trunk_access_code+international_prefix+'([1-9]%d+)#$', :replacement => 'f-cfo-+%1', },
+ { :pattern => '^%*%*?62%*'+trunk_access_code+national_prefix+'([1-9]%d+)#$', :replacement => 'f-cfo-+'+country_code+'%1', },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^%*%*?62%*'+trunk_access_code+'([1-9]%d+)#$', :replacement => 'f-cfo-+'+country_code+area_code+'%1' }
+ end
+
+ CallRoute.create_prerouting_entry('call forward if offline', elements)
+
+ CallRoute.create_prerouting_entry('deactivate call forward if offline', [
+ { :pattern => '^#62#$', :replacement => 'f-cfooff', },
+ ])
+
+ CallRoute.create_prerouting_entry('delete call forward if offline', [
+ { :pattern => '^##62#$', :replacement => 'f-cfodel', },
+ ])
+
+ elements = [
+ { :pattern => '^%*67#$', :replacement => 'f-cfb', },
+ { :pattern => '^%*%*?67%*(%+?[1-9]%d+)#$', :replacement => 'f-cfb-%1', },
+ { :pattern => '^%*%*?67%*'+trunk_access_code+international_prefix+'([1-9]%d+)#$', :replacement => 'f-cfb-+%1', },
+ { :pattern => '^%*%*?67%*'+trunk_access_code+national_prefix+'([1-9]%d+)#$', :replacement => 'f-cfb-+'+country_code+'%1', },
+ ]
+
+ if !trunk_access_code.blank? && !area_code.blank?
+ elements << { :pattern => '^%*%*?67%*'+trunk_access_code+'([1-9]%d+)#$', :replacement => 'f-cfb-+'+country_code+area_code+'%1' }
+ end
+
+ CallRoute.create_prerouting_entry('call forward if busy', elements)
+
+ CallRoute.create_prerouting_entry('deactivate call forward if busy', [
+ { :pattern => '^#67#$', :replacement => 'f-cfboff', },
+ ])
+
+ CallRoute.create_prerouting_entry('delete call forward if busy', [
+ { :pattern => '^##67#$', :replacement => 'f-cfbdel', },
+ ])
+
+
+ CallRoute.create_prerouting_entry('redial', [
+ { :pattern => '^%*66#$', :replacement => 'f-redial', },
+ ])
+
+ CallRoute.create_prerouting_entry('check voicemail', [
+ { :pattern => '^%*98$', :replacement => 'f-vmcheck', },
+ { :pattern => '^%*98#$', :replacement => 'f-vmcheck', },
+ { :pattern => '^%*98%*(%+?%d+)#$', :replacement => 'f-vmcheck-%1', },
+ ])
+
+ CallRoute.create_prerouting_entry('acivate auto logout', [
+ { :pattern => '^%*1337%*1%*1#$', :replacement => 'f-loaon', },
+ ])
+
+ CallRoute.create_prerouting_entry('deacivate auto logout', [
+ { :pattern => '^%*1337%*1%*0#$', :replacement => 'f-loaoff', },
+ ])
+ end
+
+ def self.create_prerouting_entry(name, elements, endpoint_type = 'dialplanfunction')
+ call_route = CallRoute.create(:routing_table => 'prerouting', :name => name, :endpoint_type => endpoint_type)
+
+ if !call_route.errors.any? then
+ elements.each do |element|
+ call_route.route_elements.create(
+ :var_in => 'destination_number',
+ :var_out => 'destination_number',
+ :pattern => element[:pattern],
+ :replacement => element[:replacement],
+ :action => 'match',
+ :mandatory => false
+ )
+ end
+ end
+ end
+end
diff --git a/app/models/callthrough.rb b/app/models/callthrough.rb
index c057fa6..ae461cf 100644
--- a/app/models/callthrough.rb
+++ b/app/models/callthrough.rb
@@ -5,7 +5,7 @@ class Callthrough < ActiveRecord::Base
# Validations and Associations
#
- belongs_to :tenant
+ belongs_to :tenant, :touch => true
validates_presence_of :tenant_id
validates_presence_of :tenant
diff --git a/app/models/conference.rb b/app/models/conference.rb
index 8be9f21..8c5a752 100644
--- a/app/models/conference.rb
+++ b/app/models/conference.rb
@@ -3,7 +3,7 @@ class Conference < ActiveRecord::Base
:open_for_anybody, :max_members, :announce_new_member_by_name,
:announce_left_member_by_name
- belongs_to :conferenceable, :polymorphic => true
+ belongs_to :conferenceable, :polymorphic => true, :touch => true
has_many :conference_invitees, :dependent => :destroy
has_many :phone_numbers, :as => :phone_numberable, :dependent => :destroy
@@ -15,7 +15,7 @@ class Conference < ActiveRecord::Base
validates_presence_of :max_members
validates_numericality_of :max_members, :only_integer => true,
:greater_than => 0,
- :less_than => (MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE + 1),
+ :less_than => ((GsParameter.get('MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE').nil? ? 10 : GsParameter.get('MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE')) + 1),
:allow_nil => false,
:allow_blank => false
@@ -25,7 +25,7 @@ class Conference < ActiveRecord::Base
:greater_than => 0,
:allow_nil => true,
:allow_blank => true
- validates_length_of :pin, :minimum => MINIMUM_PIN_LENGTH,
+ validates_length_of :pin, :minimum => (GsParameter.get('MINIMUM_PIN_LENGTH').nil? ? 4 : GsParameter.get('MINIMUM_PIN_LENGTH')),
:allow_nil => true,
:allow_blank => true
diff --git a/app/models/conference_invitee.rb b/app/models/conference_invitee.rb
index 7de20de..d6e3bac 100644
--- a/app/models/conference_invitee.rb
+++ b/app/models/conference_invitee.rb
@@ -13,7 +13,7 @@ class ConferenceInvitee < ActiveRecord::Base
:greater_than => 0,
:allow_nil => true,
:allow_blank => true
- validates_length_of :pin, :minimum => MINIMUM_PIN_LENGTH,
+ validates_length_of :pin, :minimum => (GsParameter.get('MINIMUM_PIN_LENGTH').nil? ? 4 : GsParameter.get('MINIMUM_PIN_LENGTH')),
:allow_nil => true,
:allow_blank => true
diff --git a/app/models/fax_document.rb b/app/models/fax_document.rb
index 67bdea9..080bdaa 100644
--- a/app/models/fax_document.rb
+++ b/app/models/fax_document.rb
@@ -54,7 +54,7 @@ class FaxDocument < ActiveRecord::Base
private
def render_thumbnails
- directory = "/tmp/GS-#{GEMEINSCHAFT_VERSION}/fax_thumbnails/#{self.id}"
+ directory = "/tmp/GS-#{GsParameter.get('GEMEINSCHAFT_VERSION')}/fax_thumbnails/#{self.id}"
system('mkdir -p ' + directory)
system("cd #{directory} && convert #{Rails.root.to_s}/public#{self.document.to_s}[0-100] -colorspace Gray PNG:'fax_page.png'")
number_of_thumbnails = Dir["#{directory}/fax_page-*.png"].count
@@ -70,7 +70,7 @@ class FaxDocument < ActiveRecord::Base
def convert_pdf_to_tiff
page_size_a4 = '595 842'
page_size_command = "<< /Policies << /PageSize 3 >> /InputAttributes currentpagedevice /InputAttributes get dup { pop 1 index exch undef } forall dup 0 << /PageSize [ #{page_size_a4} ] >> put >> setpagedevice"
- directory = "/tmp/GS-#{GEMEINSCHAFT_VERSION}/faxes/#{self.id}"
+ directory = "/tmp/GS-#{GsParameter.get('GEMEINSCHAFT_VERSION')}/faxes/#{self.id}"
system('mkdir -p ' + directory)
tiff_file_name = File.basename(self.document.to_s.downcase, ".pdf") + '.tiff'
system "cd #{directory} && gs -q -r#{self.fax_resolution.resolution_value} -dNOPAUSE -dBATCH -dSAFER -sDEVICE=tiffg3 -sOutputFile=\"#{tiff_file_name}\" -c \"#{page_size_command}\" -- \"#{Rails.root.to_s}/public#{self.document.to_s}\""
diff --git a/app/models/gateway.rb b/app/models/gateway.rb
new file mode 100644
index 0000000..3e791a6
--- /dev/null
+++ b/app/models/gateway.rb
@@ -0,0 +1,35 @@
+class Gateway < ActiveRecord::Base
+ TECHNOLOGIES = ['sip']
+
+ attr_accessible :name, :technology, :inbound, :outbound, :description
+
+ has_many :gateway_settings, :dependent => :destroy
+ has_many :gateway_parameters, :dependent => :destroy
+
+ validates :name,
+ :presence => true,
+ :uniqueness => true
+
+ validates :technology,
+ :presence => true,
+ :inclusion => { :in => TECHNOLOGIES }
+
+ after_initialize :set_defaults
+ before_validation :downcase_technology
+
+ def to_s
+ name
+ end
+
+ private
+ def downcase_technology
+ self.technology = self.technology.downcase if !self.technology.blank?
+ end
+
+ def set_defaults
+ if TECHNOLOGIES.count == 1
+ self.technology = TECHNOLOGIES.first
+ end
+ end
+
+end
diff --git a/app/models/gateway_parameter.rb b/app/models/gateway_parameter.rb
new file mode 100644
index 0000000..a66af75
--- /dev/null
+++ b/app/models/gateway_parameter.rb
@@ -0,0 +1,19 @@
+class GatewayParameter < ActiveRecord::Base
+ CLASS_TYPES = ['String', 'Integer', 'Boolean']
+
+ attr_accessible :gateway_id, :name, :value, :class_type, :description
+
+ belongs_to :gateway, :touch => true
+
+ validates :name,
+ :presence => true,
+ :uniqueness => {:scope => :gateway_id}
+
+ validates :class_type,
+ :presence => true,
+ :inclusion => { :in => CLASS_TYPES }
+
+ def to_s
+ name
+ end
+end
diff --git a/app/models/gateway_setting.rb b/app/models/gateway_setting.rb
new file mode 100644
index 0000000..c01f0a8
--- /dev/null
+++ b/app/models/gateway_setting.rb
@@ -0,0 +1,31 @@
+class GatewaySetting < ActiveRecord::Base
+ CLASS_TYPES = ['String', 'Integer', 'Boolean']
+ GATEWAY_SETTINGS = {
+ 'sip' => {
+ 'domain' => 'String',
+ 'username' => 'String',
+ 'password' => 'String',
+ 'contact' => 'String',
+ 'register' => 'Boolean',
+ 'auth_source' => 'String',
+ 'auth_pattern' => 'String',
+ 'number_source' => 'String',
+ },
+ }
+
+ attr_accessible :gateway_id, :name, :value, :class_type, :description
+
+ belongs_to :gateway
+
+ validates :name,
+ :presence => true,
+ :uniqueness => {:scope => :gateway_id}
+
+ validates :class_type,
+ :presence => true,
+ :inclusion => { :in => CLASS_TYPES }
+
+ def to_s
+ name
+ end
+end
diff --git a/app/models/gemeinschaft_setup.rb b/app/models/gemeinschaft_setup.rb
index b445b21..6056236 100644
--- a/app/models/gemeinschaft_setup.rb
+++ b/app/models/gemeinschaft_setup.rb
@@ -5,4 +5,25 @@ class GemeinschaftSetup < ActiveRecord::Base
accepts_nested_attributes_for :sip_domain
belongs_to :country
belongs_to :language
+
+ # Remove the cache which was created by the heater rake task.
+ #
+ after_create :expire_cache
+
+ before_validation :format_default_area_code
+
+ private
+ def expire_cache
+ ActionController::Base.expire_page(Rails.application.routes.url_helpers.new_gemeinschaft_setup_path)
+ end
+
+ def format_default_area_code
+ if self.default_area_code.blank?
+ self.default_area_code = nil
+ else
+ if self.country != nil && !self.country.trunk_prefix.blank?
+ self.default_area_code.gsub(/^#{self.country.trunk_prefix}/,'')
+ end
+ end
+ end
end
diff --git a/app/models/gs_cluster_sync_log_entry.rb b/app/models/gs_cluster_sync_log_entry.rb
index 063ff23..51e3b05 100644
--- a/app/models/gs_cluster_sync_log_entry.rb
+++ b/app/models/gs_cluster_sync_log_entry.rb
@@ -15,7 +15,7 @@ class GsClusterSyncLogEntry < ActiveRecord::Base
after_create :apply_to_local_database
def apply_to_local_database
- if self.homebase_ip_address != HOMEBASE_IP_ADDRESS
+ if self.homebase_ip_address != GsParameter.get('HOMEBASE_IP_ADDRESS')
if self.class_name.constantize.new.attribute_names.include?('is_native')
case self.action
when 'create'
@@ -84,7 +84,7 @@ class GsClusterSyncLogEntry < ActiveRecord::Base
end
def populate_other_cluster_nodes
- if self.homebase_ip_address == HOMEBASE_IP_ADDRESS && self.waiting_to_be_synced == true
+ if self.homebase_ip_address == GsParameter.get('HOMEBASE_IP_ADDRESS') && self.waiting_to_be_synced == true
if GsNode.where(:push_updates_to => true).count > 0
GsNode.where(:push_updates_to => true).each do |gs_node|
RemoteGsNode::GsClusterSyncLogEntry.site = gs_node.site
diff --git a/app/models/gs_parameter.rb b/app/models/gs_parameter.rb
new file mode 100644
index 0000000..fe2a845
--- /dev/null
+++ b/app/models/gs_parameter.rb
@@ -0,0 +1,35 @@
+class GsParameter < ActiveRecord::Base
+ # https://github.com/rails/strong_parameters
+ include ActiveModel::ForbiddenAttributesProtection
+
+ validates :name,
+ :presence => true,
+ :uniqueness => { :scope => [ :entity, :section ] }
+
+ validates :class_type,
+ :presence => true,
+ :inclusion => { :in => ['String', 'Integer', 'Boolean', 'YAML', 'Nil'] }
+
+ def self.get(wanted_variable)
+ if GsParameter.table_exists?
+ item = GsParameter.where(:name => wanted_variable).first
+ if item.nil? || item.class_type == 'Nil'
+ return nil
+ else
+ return item.value.to_i if item.class_type == 'Integer'
+ return item.value.to_s if item.class_type == 'String'
+ if item.class_type == 'Boolean'
+ return true if item.value == 'true'
+ return false if item.value == 'false'
+ end
+ return YAML.load(item.value) if item.class_type == 'YAML'
+ end
+ else
+ nil
+ end
+ end
+
+ def to_s
+ name
+ end
+end
diff --git a/app/models/hunt_group.rb b/app/models/hunt_group.rb
index 276ae53..5011bf0 100644
--- a/app/models/hunt_group.rb
+++ b/app/models/hunt_group.rb
@@ -1,24 +1,24 @@
class HuntGroup < ActiveRecord::Base
attr_accessible :name, :strategy, :seconds_between_jumps, :phone_numbers_attributes
- belongs_to :tenant
+ belongs_to :tenant, :touch => true
has_many :call_forwards, :as => :call_forwardable, :dependent => :destroy
validates_uniqueness_of :name, :scope => :tenant_id,
:allow_nil => true, :allow_blank => true
validates_presence_of :strategy
- validates_inclusion_of :strategy, :in => HUNT_GROUP_STRATEGIES
+ validates_inclusion_of :strategy, :in => (GsParameter.get('HUNT_GROUP_STRATEGIES').nil? ? [] : GsParameter.get('HUNT_GROUP_STRATEGIES'))
validates_presence_of :seconds_between_jumps,
:if => Proc.new{ |hunt_group| hunt_group.strategy != 'ring_all' }
validates_numericality_of :seconds_between_jumps,
:only_integer => true,
- :greater_than_or_equal_to => VALID_SECONDS_BETWEEN_JUMPS_VALUES.min,
- :less_than_or_equal_to => VALID_SECONDS_BETWEEN_JUMPS_VALUES.max,
+ :greater_than_or_equal_to => (GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES').nil? ? 2 : GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES').min),
+ :less_than_or_equal_to => (GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES').nil? ? 120 : GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES').max),
:if => Proc.new{ |hunt_group| hunt_group.strategy != 'ring_all' }
validates_inclusion_of :seconds_between_jumps,
- :in => VALID_SECONDS_BETWEEN_JUMPS_VALUES,
+ :in => (GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES').nil? ? [] : GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES')),
:if => Proc.new{ |hunt_group| hunt_group.strategy != 'ring_all' }
validates_inclusion_of :seconds_between_jumps,
:in => [nil],
diff --git a/app/models/phone.rb b/app/models/phone.rb
index a606834..8b41b59 100644
--- a/app/models/phone.rb
+++ b/app/models/phone.rb
@@ -9,7 +9,7 @@ class Phone < ActiveRecord::Base
# Associations
#
belongs_to :phone_model
- belongs_to :phoneable, :polymorphic => true
+ belongs_to :phoneable, :polymorphic => true, :touch => true
has_many :phone_sip_accounts, :dependent => :destroy, :uniq => true, :order => :position
has_many :sip_accounts, :through => :phone_sip_accounts
@@ -162,7 +162,6 @@ class Phone < ActiveRecord::Base
if ! self.resync(true, sip_account_resync)
errors.add(:resync, "Resync failed")
- return false
end
return true
@@ -201,6 +200,10 @@ class Phone < ActiveRecord::Base
# Sanitize MAC address.
#
def sanitize_mac_address
+ if self.mac_address.split(/:/).count == 6 && self.mac_address.length < 17
+ splitted_mac_address = self.mac_address.split(/:/)
+ self.mac_address = splitted_mac_address.map{|part| (part.size == 1 ? "0#{part}" : part)}.join('')
+ end
self.mac_address = self.mac_address.to_s.upcase.gsub( /[^A-F0-9]/, '' )
end
diff --git a/app/models/phone_book.rb b/app/models/phone_book.rb
index 3603eae..21d30c0 100644
--- a/app/models/phone_book.rb
+++ b/app/models/phone_book.rb
@@ -1,7 +1,7 @@
class PhoneBook < ActiveRecord::Base
attr_accessible :name, :description, :uuid
- belongs_to :phone_bookable, :polymorphic => true
+ belongs_to :phone_bookable, :polymorphic => true, :touch => true
has_many :phone_book_entries, :dependent => :destroy
validates_presence_of :name
diff --git a/app/models/phone_book_entry.rb b/app/models/phone_book_entry.rb
index db2b44b..275c7b6 100644
--- a/app/models/phone_book_entry.rb
+++ b/app/models/phone_book_entry.rb
@@ -6,7 +6,7 @@ class PhoneBookEntry < ActiveRecord::Base
attr_accessible :first_name, :middle_name, :last_name, :title, :nickname, :organization, :is_organization, :department, :job_title, :is_male, :birthday, :birth_name, :description, :homepage_personal, :homepage_organization, :twitter_account, :facebook_account, :google_plus_account, :xing_account, :linkedin_account, :mobileme_account, :image
- belongs_to :phone_book
+ belongs_to :phone_book, :touch => true
has_many :conference_invitees, :dependent => :destroy
acts_as_list :scope => :phone_book
diff --git a/app/models/phone_model.rb b/app/models/phone_model.rb
index e00e0e3..ac4d4a3 100644
--- a/app/models/phone_model.rb
+++ b/app/models/phone_model.rb
@@ -3,7 +3,7 @@ class PhoneModel < ActiveRecord::Base
# Associations
#
- belongs_to :manufacturer
+ belongs_to :manufacturer, :touch => true
has_many :phones, :dependent => :destroy
diff --git a/app/models/phone_number.rb b/app/models/phone_number.rb
index 4c0cf46..d1e950f 100644
--- a/app/models/phone_number.rb
+++ b/app/models/phone_number.rb
@@ -18,8 +18,8 @@ class PhoneNumber < ActiveRecord::Base
before_save :save_value_of_to_s
after_create :copy_existing_call_forwards_if_necessary
before_validation :'parse_and_split_number!'
- validate :validate_number, :if => Proc.new { |phone_number| STRICT_INTERNAL_EXTENSION_HANDLING && STRICT_DID_HANDLING }
- validate :check_if_number_is_available, :if => Proc.new { |phone_number| STRICT_INTERNAL_EXTENSION_HANDLING && STRICT_DID_HANDLING }
+ validate :validate_number, :if => Proc.new { |phone_number| GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') && GsParameter.get('STRICT_DID_HANDLING') }
+ validate :check_if_number_is_available, :if => Proc.new { |phone_number| GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') && GsParameter.get('STRICT_DID_HANDLING') }
acts_as_list :scope => [:phone_numberable_id, :phone_numberable_type]
@@ -95,7 +95,7 @@ class PhoneNumber < ActiveRecord::Base
else
# Check if the number is an internal extension.
if tenant
- internal_extension_range = tenant.phone_number_ranges.where(:name => INTERNAL_EXTENSIONS).first
+ internal_extension_range = tenant.phone_number_ranges.where(:name => GsParameter.get('INTERNAL_EXTENSIONS')).first
if internal_extension_range
if internal_extension_range.phone_numbers.where(:number => number).length > 0
parts[:extension] = number
@@ -192,8 +192,8 @@ class PhoneNumber < ActiveRecord::Base
end
def parse_and_split_number!
- if self.phone_numberable_type == 'PhoneNumberRange' && self.phone_numberable.name == INTERNAL_EXTENSIONS
- # The parent is the PhoneNumberRange INTERNAL_EXTENSIONS. Therefor it must be an extensions.
+ if self.phone_numberable_type == 'PhoneNumberRange' && self.phone_numberable.name == GsParameter.get('INTERNAL_EXTENSIONS')
+ # The parent is the PhoneNumberRange GsParameter.get('INTERNAL_EXTENSIONS'). Therefor it must be an extensions.
#
self.country_code = nil
self.area_code = nil
@@ -202,8 +202,8 @@ class PhoneNumber < ActiveRecord::Base
self.extension = self.number.to_s.strip
else
if self.tenant &&
- self.tenant.phone_number_ranges.exists?(:name => INTERNAL_EXTENSIONS) &&
- self.tenant.phone_number_ranges.where(:name => INTERNAL_EXTENSIONS).first.phone_numbers.exists?(:number => self.number)
+ self.tenant.phone_number_ranges.exists?(:name => GsParameter.get('INTERNAL_EXTENSIONS')) &&
+ self.tenant.phone_number_ranges.where(:name => GsParameter.get('INTERNAL_EXTENSIONS')).first.phone_numbers.exists?(:number => self.number)
self.country_code = nil
self.area_code = nil
self.subscriber_number = nil
@@ -263,7 +263,7 @@ class PhoneNumber < ActiveRecord::Base
if self.phone_numberable_type != 'PhoneBookEntry' && self.tenant
phone_number_ranges = self.tenant.phone_number_ranges.where(
- :name => [INTERNAL_EXTENSIONS, DIRECT_INWARD_DIALING_NUMBERS]
+ :name => [GsParameter.get('INTERNAL_EXTENSIONS'), GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')]
)
if !phone_number_ranges.empty?
if !PhoneNumber.where(:phone_numberable_type => 'PhoneNumberRange').
diff --git a/app/models/phone_number_range.rb b/app/models/phone_number_range.rb
index 2fdd9b6..b666487 100644
--- a/app/models/phone_number_range.rb
+++ b/app/models/phone_number_range.rb
@@ -6,7 +6,7 @@ class PhoneNumberRange < ActiveRecord::Base
validates_presence_of :name
validates_uniqueness_of :name, :scope => [:phone_number_rangeable_id, :phone_number_rangeable_type]
- validates_inclusion_of :name, :in => [INTERNAL_EXTENSIONS, DIRECT_INWARD_DIALING_NUMBERS, SERVICE_NUMBERS]
+ validates_inclusion_of :name, :in => [GsParameter.get('INTERNAL_EXTENSIONS'), GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS'), GsParameter.get('SERVICE_NUMBERS')]
validates_presence_of :phone_number_rangeable_id
validates_presence_of :phone_number_rangeable
diff --git a/app/models/route_element.rb b/app/models/route_element.rb
new file mode 100644
index 0000000..94f0f84
--- /dev/null
+++ b/app/models/route_element.rb
@@ -0,0 +1,26 @@
+class RouteElement < ActiveRecord::Base
+ ELEMENT_ACTIONS = ['none', 'match', 'not_match', 'set']
+
+ attr_accessible :call_route_id, :var_in, :var_out, :pattern, :replacement, :action, :mandatory, :position
+
+ belongs_to :call_route
+
+ acts_as_list :scope => :call_route
+
+ validates :action,
+ :presence => true,
+ :inclusion => { :in => ELEMENT_ACTIONS }
+
+
+ def to_s
+ "#{pattern} => #{var_in} #{var_out}"
+ end
+
+ def move_up?
+ #return self.position.to_i > RouteElement.where(:call_route_id => self.call_route_id ).order(:position).first.position.to_i
+ end
+
+ def move_down?
+ #return self.position.to_i < RouteElement.where(:call_route_id => self.call_route_id ).order(:position).last.position.to_i
+ end
+end
diff --git a/app/models/sip_account.rb b/app/models/sip_account.rb
index 8459265..d35f9b4 100644
--- a/app/models/sip_account.rb
+++ b/app/models/sip_account.rb
@@ -10,7 +10,7 @@ class SipAccount < ActiveRecord::Base
# Associations:
#
- belongs_to :sip_accountable, :polymorphic => true
+ belongs_to :sip_accountable, :polymorphic => true, :touch => true
has_many :phone_sip_accounts, :uniq => true
has_many :phones, :through => :phone_sip_accounts
@@ -71,7 +71,7 @@ class SipAccount < ActiveRecord::Base
after_update :log_out_phone_if_not_local
def to_s
- truncate((self.caller_name || "SipAccount ID #{self.id}"), :length => TO_S_MAX_CALLER_NAME_LENGTH) + " (#{truncate(self.auth_name, :length => TO_S_MAX_LENGTH_OF_AUTH_NAME)}@...#{self.host.split(/\./)[2,3].to_a.join('.') if self.host })"
+ truncate((self.caller_name || "SipAccount ID #{self.id}"), :length => GsParameter.get('TO_S_MAX_CALLER_NAME_LENGTH')) + " (#{truncate(self.auth_name, :length => GsParameter.get('TO_S_MAX_LENGTH_OF_AUTH_NAME'))}@...#{self.host.split(/\./)[2,3].to_a.join('.') if self.host })"
end
def call_forwarding_toggle( call_forwarding_service, to_voicemail = nil )
@@ -200,7 +200,7 @@ class SipAccount < ActiveRecord::Base
# log out phone if sip_account is not on this node
def log_out_phone_if_not_local
- if self.gs_node_id && ! GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS, :id => self.gs_node_id).first
+ if self.gs_node_id && ! GsNode.where(:ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS'), :id => self.gs_node_id).first
self.phones.each do |phone|
phone.user_logout;
end
diff --git a/app/models/tenant.rb b/app/models/tenant.rb
index d9351b7..419ac3a 100644
--- a/app/models/tenant.rb
+++ b/app/models/tenant.rb
@@ -1,15 +1,8 @@
# encoding: UTF-8
class Tenant < ActiveRecord::Base
- attr_accessible :name, :description, :sip_domain_id, :country_id, :language_id, :from_field_pin_change_email, :from_field_voicemail_email
-
- if STRICT_INTERNAL_EXTENSION_HANDLING == true
- attr_accessible :internal_extension_ranges
- end
-
- if STRICT_DID_HANDLING == true
- attr_accessible :did_list
- end
+ # https://github.com/rails/strong_parameters
+ include ActiveModel::ForbiddenAttributesProtection
# Associations:
#
@@ -93,7 +86,7 @@ class Tenant < ActiveRecord::Base
name
end
- if STRICT_INTERNAL_EXTENSION_HANDLING == true
+ if GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') == true
def array_of_internal_extension_numbers
ranges = self.internal_extension_ranges.gsub(/[^0-9\-,]/,'').gsub(/[\-]+/,'-').gsub(/[,]+/,',').split(/,/)
output = []
@@ -112,7 +105,7 @@ class Tenant < ActiveRecord::Base
# Generate the internal_extensions
#
def generate_internal_extensions
- internal_extensions = self.phone_number_ranges.find_or_create_by_name(INTERNAL_EXTENSIONS, :description => 'A list of all available internal extensions.')
+ internal_extensions = self.phone_number_ranges.find_or_create_by_name(GsParameter.get('INTERNAL_EXTENSIONS'), :description => 'A list of all available internal extensions.')
phone_number_list = Array.new
@@ -122,7 +115,7 @@ class Tenant < ActiveRecord::Base
elsif
# Don't create extensions like 911, 110 or 112 (at least by default)
#
- phone_number_list = (self.array_of_internal_extension_numbers - self.country.phone_number_ranges.where(:name => SERVICE_NUMBERS).first.phone_numbers.map{|entry| entry.number})
+ phone_number_list = (self.array_of_internal_extension_numbers - self.country.phone_number_ranges.where(:name => GsParameter.get('SERVICE_NUMBERS')).first.phone_numbers.map{|entry| entry.number})
end
end
@@ -133,7 +126,7 @@ class Tenant < ActiveRecord::Base
end
- if STRICT_DID_HANDLING == true
+ if GsParameter.get('STRICT_DID_HANDLING') == true
def array_of_dids_generated_from_did_list
numbers = self.did_list.downcase.gsub(/[^0-9,x\+]/,'').gsub(/[,]+/,',').split(/,/)
array_of_all_external_numbers = []
@@ -152,7 +145,7 @@ class Tenant < ActiveRecord::Base
# Generate the external numbers (DIDs)
#
def generate_dids
- dids = self.phone_number_ranges.find_or_create_by_name(DIRECT_INWARD_DIALING_NUMBERS, :description => 'A list of all available DIDs.')
+ dids = self.phone_number_ranges.find_or_create_by_name(GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS'), :description => 'A list of all available DIDs.')
self.array_of_dids_generated_from_did_list.each do |number|
dids.phone_numbers.find_or_create_by_name_and_number('DID', number)
end
@@ -167,7 +160,7 @@ class Tenant < ActiveRecord::Base
@internal_extensions_and_dids ||= self.phone_number_ranges_phone_numbers.
where(:phone_numberable_type => 'PhoneNumberRange').
where(:phone_numberable_id => self.phone_number_ranges.
- where(:name => [INTERNAL_EXTENSIONS, DIRECT_INWARD_DIALING_NUMBERS]).
+ where(:name => [GsParameter.get('INTERNAL_EXTENSIONS'), GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')]).
map{|pnr| pnr.id })
end
@@ -175,7 +168,7 @@ class Tenant < ActiveRecord::Base
@array_of_internal_extensions ||= self.phone_number_ranges_phone_numbers.
where(:phone_numberable_type => 'PhoneNumberRange').
where(:phone_numberable_id => self.phone_number_ranges.
- where(:name => INTERNAL_EXTENSIONS).
+ where(:name => GsParameter.get('INTERNAL_EXTENSIONS')).
map{|pnr| pnr.id }).
map{|phone_number| phone_number.number }.
sort.uniq
@@ -184,7 +177,7 @@ class Tenant < ActiveRecord::Base
def array_of_dids
@array_of_dids ||= self.phone_number_ranges_phone_numbers.
where(:phone_numberable_type => 'PhoneNumberRange').
- where(:phone_numberable_id => self.phone_number_ranges.where(:name => DIRECT_INWARD_DIALING_NUMBERS).map{|pnr| pnr.id }).
+ where(:phone_numberable_id => self.phone_number_ranges.where(:name => GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')).map{|pnr| pnr.id }).
map{|phone_number| phone_number.to_s }.
sort.uniq
end
@@ -215,7 +208,7 @@ class Tenant < ActiveRecord::Base
# Create a public phone book for this tenant
def create_a_default_phone_book
- if self.name != SUPER_TENANT_NAME
+ if self.name != GsParameter.get('SUPER_TENANT_NAME')
general_phone_book = self.phone_books.find_or_create_by_name_and_description(
I18n.t('phone_books.general_phone_book.name'),
I18n.t('phone_books.general_phone_book.description', :resource => self.to_s)
diff --git a/app/models/user.rb b/app/models/user.rb
index 2d0256f..b902b99 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -27,7 +27,8 @@ class User < ActiveRecord::Base
}
validates_length_of [:new_pin, :new_pin_confirmation],
- :minimum => MINIMUM_PIN_LENGTH, :maximum => MAXIMUM_PIN_LENGTH,
+ :minimum => (GsParameter.get('MINIMUM_PIN_LENGTH').nil? ? 4 : GsParameter.get('MINIMUM_PIN_LENGTH')),
+ :maximum => (GsParameter.get('MAXIMUM_PIN_LENGTH').nil? ? 10 : GsParameter.get('MAXIMUM_PIN_LENGTH')),
:allow_blank => true, :allow_nil => true
validates_format_of [:new_pin, :new_pin_confirmation],
:with => /^[0-9]+$/,
@@ -202,6 +203,7 @@ class User < ActiveRecord::Base
else
phone.destroy
end
+ phone.resync
end
end
diff --git a/app/views/access_authorizations/_index_core.html.haml b/app/views/access_authorizations/_index_core.html.haml
index 083b16b..7469a1d 100644
--- a/app/views/access_authorizations/_index_core.html.haml
+++ b/app/views/access_authorizations/_index_core.html.haml
@@ -1,15 +1,15 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('access_authorizations.index.name')
%th= t('access_authorizations.index.login')
%th= t('access_authorizations.index.pin')
%th= t('callthroughs.index.phone_numbers')
- - reset_cycle
+
- for access_authorization in access_authorizations
- show_path_method = method( :"#{access_authorization.access_authorizationable.class.name.underscore}_access_authorization_path" )
- edit_path_method = method( :"edit_#{access_authorization.access_authorizationable.class.name.underscore}_access_authorization_path" )
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= access_authorization.name
%td= access_authorization.login
%td= access_authorization.pin
diff --git a/app/views/access_authorizations/edit.html.haml b/app/views/access_authorizations/edit.html.haml
index 414f094..b05c23e 100644
--- a/app/views/access_authorizations/edit.html.haml
+++ b/app/views/access_authorizations/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("access_authorizations.edit.page_title")
+- content_for :title, t("access_authorizations.edit.page_title")
= render "form"
diff --git a/app/views/access_authorizations/index.html.haml b/app/views/access_authorizations/index.html.haml
index 05b27db..7a0dfd3 100644
--- a/app/views/access_authorizations/index.html.haml
+++ b/app/views/access_authorizations/index.html.haml
@@ -1,4 +1,4 @@
-- title t("access_authorizations.index.page_title")
+- content_for :title, t("access_authorizations.index.page_title")
- if @access_authorizations.count > 0
= render "index_core", :access_authorizations => @access_authorizations
diff --git a/app/views/access_authorizations/new.html.haml b/app/views/access_authorizations/new.html.haml
index 0bbf16c..f1ba872 100644
--- a/app/views/access_authorizations/new.html.haml
+++ b/app/views/access_authorizations/new.html.haml
@@ -1,3 +1,3 @@
-- title t("access_authorizations.new.page_title")
+- content_for :title, t("access_authorizations.new.page_title")
= render "form"
diff --git a/app/views/access_authorizations/show.html.haml b/app/views/access_authorizations/show.html.haml
index 17d1d9b..f39a509 100644
--- a/app/views/access_authorizations/show.html.haml
+++ b/app/views/access_authorizations/show.html.haml
@@ -1,4 +1,4 @@
-- title t("access_authorizations.show.page_title")
+- content_for :title, t("access_authorizations.show.page_title")
%p
%strong= t('access_authorizations.show.name') + ":"
diff --git a/app/views/acd_agents/_index_core.html.haml b/app/views/acd_agents/_index_core.html.haml
index 7cb1aae..c082fd1 100644
--- a/app/views/acd_agents/_index_core.html.haml
+++ b/app/views/acd_agents/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('acd_agents.index.name')
%th= t('acd_agents.index.status')
@@ -6,9 +6,9 @@
%th= t('acd_agents.index.calls_answered')
%th= t('acd_agents.index.destination')
- - reset_cycle
+
- for acd_agent in acd_agents
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= acd_agent.name
%td= acd_agent.status
%td= acd_agent.last_call
diff --git a/app/views/acd_agents/edit.html.haml b/app/views/acd_agents/edit.html.haml
index 8ab14b8..41671b2 100644
--- a/app/views/acd_agents/edit.html.haml
+++ b/app/views/acd_agents/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("acd_agents.edit.page_title")
+- content_for :title, t("acd_agents.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/acd_agents/index.html.haml b/app/views/acd_agents/index.html.haml
index d586dcf..ddf5fde 100644
--- a/app/views/acd_agents/index.html.haml
+++ b/app/views/acd_agents/index.html.haml
@@ -1,4 +1,4 @@
-- title t("acd_agents.index.page_title")
+- content_for :title, t("acd_agents.index.page_title")
- if @acd_agents && @acd_agents.count > 0
= render "index_core", :acd_agents => @acd_agents
diff --git a/app/views/acd_agents/new.html.haml b/app/views/acd_agents/new.html.haml
index 546136b..fb4d256 100644
--- a/app/views/acd_agents/new.html.haml
+++ b/app/views/acd_agents/new.html.haml
@@ -1,3 +1,3 @@
-- title t("acd_agents.new.page_title")
+- content_for :title, t("acd_agents.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/acd_agents/show.html.haml b/app/views/acd_agents/show.html.haml
index 0c90f4b..39c0036 100644
--- a/app/views/acd_agents/show.html.haml
+++ b/app/views/acd_agents/show.html.haml
@@ -1,4 +1,4 @@
-- title t("acd_agents.show.page_title")
+- content_for :title, t("acd_agents.show.page_title")
%p
%strong= t('acd_agents.show.name') + ":"
diff --git a/app/views/acd_callers/_index_core.html.haml b/app/views/acd_callers/_index_core.html.haml
index 958b3ff..79aa974 100644
--- a/app/views/acd_callers/_index_core.html.haml
+++ b/app/views/acd_callers/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('acd_callers.index.channel_uuid')
%th= t('acd_callers.index.automatic_call_distributor_id')
@@ -8,9 +8,9 @@
%th= t('acd_callers.index.callback_number')
%th= t('acd_callers.index.callback_attempts')
- - reset_cycle
+
- for acd_caller in acd_callers
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= acd_caller.channel_uuid
%td= acd_caller.automatic_call_distributor_id
%td= acd_caller.status
diff --git a/app/views/acd_callers/index.html.haml b/app/views/acd_callers/index.html.haml
index 70439ed..7047600 100644
--- a/app/views/acd_callers/index.html.haml
+++ b/app/views/acd_callers/index.html.haml
@@ -1,4 +1,4 @@
-- title t("acd_callers.index.page_title")
+- content_for :title, t("acd_callers.index.page_title")
- if @acd_callers && @acd_callers.count > 0
= render "index_core", :acd_callers => @acd_callers
diff --git a/app/views/acd_callers/show.html.haml b/app/views/acd_callers/show.html.haml
index 0ce8345..060f829 100644
--- a/app/views/acd_callers/show.html.haml
+++ b/app/views/acd_callers/show.html.haml
@@ -1,4 +1,4 @@
-- title t("acd_callers.show.page_title")
+- content_for :title, t("acd_callers.show.page_title")
%p
%strong= t('acd_callers.show.channel_uuid') + ":"
diff --git a/app/views/addresses/_index_core.html.haml b/app/views/addresses/_index_core.html.haml
index 2050ded..3645009 100644
--- a/app/views/addresses/_index_core.html.haml
+++ b/app/views/addresses/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('addresses.index.phone_book_entry_id')
%th= t('addresses.index.line1')
@@ -9,9 +9,9 @@
%th= t('addresses.index.country_id')
%th= t('addresses.index.position')
- - reset_cycle
+
- for address in addresses
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= address.phone_book_entry_id
%td= address.line1
%td= address.line2
diff --git a/app/views/addresses/edit.html.haml b/app/views/addresses/edit.html.haml
index 3d85ae6..a9e482f 100644
--- a/app/views/addresses/edit.html.haml
+++ b/app/views/addresses/edit.html.haml
@@ -1,4 +1,4 @@
-- title t("addresses.edit.page_title")
+- content_for :title, t("addresses.edit.page_title")
= render "form"
diff --git a/app/views/addresses/index.html.haml b/app/views/addresses/index.html.haml
index ecebc65..615f267 100644
--- a/app/views/addresses/index.html.haml
+++ b/app/views/addresses/index.html.haml
@@ -1,4 +1,4 @@
-- title t("addresses.index.page_title")
+- content_for :title, t("addresses.index.page_title")
- if @addresses.count > 0
= render "index_core", :addresses => @addresses
diff --git a/app/views/addresses/new.html.haml b/app/views/addresses/new.html.haml
index 280de55..e75b55a 100644
--- a/app/views/addresses/new.html.haml
+++ b/app/views/addresses/new.html.haml
@@ -1,3 +1,3 @@
-- title t("addresses.new.page_title")
+- content_for :title, t("addresses.new.page_title")
= render "form"
diff --git a/app/views/addresses/show.html.haml b/app/views/addresses/show.html.haml
index 211d020..6c8c651 100644
--- a/app/views/addresses/show.html.haml
+++ b/app/views/addresses/show.html.haml
@@ -1,4 +1,4 @@
-- title t("addresses.show.page_title")
+- content_for :title, t("addresses.show.page_title")
%p
%strong= t('addresses.show.phone_book_entry_id') + ":"
diff --git a/app/views/automatic_call_distributors/_form_core.html.haml b/app/views/automatic_call_distributors/_form_core.html.haml
index 77a38a6..d315ff3 100644
--- a/app/views/automatic_call_distributors/_form_core.html.haml
+++ b/app/views/automatic_call_distributors/_form_core.html.haml
@@ -1,5 +1,5 @@
.inputs
- = f.input :name, :label => t('automatic_call_distributors.form.name.label'), :hint => conditional_hint('automatic_call_distributors.form.name.hint')
+ = f.input :name, :label => t('automatic_call_distributors.form.name.label'), :hint => conditional_hint('automatic_call_distributors.form.name.hint'), :autofocus => true
= f.input :strategy, :label => t('automatic_call_distributors.form.strategy.label'), :hint => conditional_hint('automatic_call_distributors.form.strategy.hint'), :include_blank => false, :as => :select, :collection => strategies
= f.input :max_callers, :label => t('automatic_call_distributors.form.max_callers.label'), :hint => conditional_hint('automatic_call_distributors.form.max_callers.hint')
= f.input :agent_timeout, :label => t('automatic_call_distributors.form.agent_timeout.label'), :hint => conditional_hint('automatic_call_distributors.form.agent_timeout.hint')
diff --git a/app/views/automatic_call_distributors/_index_core.html.haml b/app/views/automatic_call_distributors/_index_core.html.haml
index c31a648..50908f4 100644
--- a/app/views/automatic_call_distributors/_index_core.html.haml
+++ b/app/views/automatic_call_distributors/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('automatic_call_distributors.index.name')
%th= t('automatic_call_distributors.index.strategy')
@@ -10,9 +10,9 @@
%th= t('automatic_call_distributors.index.phone_numbers')
%th= t('automatic_call_distributors.index.acd_agents')
- - reset_cycle
+
- for automatic_call_distributor in automatic_call_distributors
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= automatic_call_distributor.name
%td= t("automatic_call_distributors.strategies.#{automatic_call_distributor.strategy}")
%td= automatic_call_distributor.max_callers
diff --git a/app/views/automatic_call_distributors/edit.html.haml b/app/views/automatic_call_distributors/edit.html.haml
index 28cba74..c776945 100644
--- a/app/views/automatic_call_distributors/edit.html.haml
+++ b/app/views/automatic_call_distributors/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("automatic_call_distributors.edit.page_title")
+- content_for :title, t("automatic_call_distributors.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/automatic_call_distributors/index.html.haml b/app/views/automatic_call_distributors/index.html.haml
index f3f8b2b..4f2d040 100644
--- a/app/views/automatic_call_distributors/index.html.haml
+++ b/app/views/automatic_call_distributors/index.html.haml
@@ -1,4 +1,4 @@
-- title t("automatic_call_distributors.index.page_title")
+- content_for :title, t("automatic_call_distributors.index.page_title")
- if @automatic_call_distributors && @automatic_call_distributors.count > 0
= render "index_core", :automatic_call_distributors => @automatic_call_distributors
diff --git a/app/views/automatic_call_distributors/new.html.haml b/app/views/automatic_call_distributors/new.html.haml
index 96a2d93..72817a7 100644
--- a/app/views/automatic_call_distributors/new.html.haml
+++ b/app/views/automatic_call_distributors/new.html.haml
@@ -1,3 +1,3 @@
-- title t("automatic_call_distributors.new.page_title")
+- content_for :title, t("automatic_call_distributors.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/automatic_call_distributors/show.html.haml b/app/views/automatic_call_distributors/show.html.haml
index 53ce127..c29f2df 100644
--- a/app/views/automatic_call_distributors/show.html.haml
+++ b/app/views/automatic_call_distributors/show.html.haml
@@ -1,6 +1,6 @@
-- title t("automatic_call_distributors.show.page_title")
+- content_for :title, t("automatic_call_distributors.show.page_title")
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('automatic_call_distributors.show.name') + ":"
%td= @automatic_call_distributor.name
diff --git a/app/views/call_forwards/_form_core.html.haml b/app/views/call_forwards/_form_core.html.haml
index 3dadb68..b751fb3 100644
--- a/app/views/call_forwards/_form_core.html.haml
+++ b/app/views/call_forwards/_form_core.html.haml
@@ -1,5 +1,5 @@
.inputs
- = f.input :call_forward_case_id, :as => :select, :collection => @available_call_forward_cases.map {|x| [I18n.t("call_forward_cases.#{x.value}"), x.id] }, :label => t('call_forwards.form.call_forward_case_id.label'), :hint => conditional_hint('call_forwards.form.call_forward_case_id.hint'), :include_blank => false
+ = f.input :call_forward_case_id, :as => :select, :collection => @available_call_forward_cases.map {|x| [I18n.t("call_forward_cases.#{x.value}"), x.id] }, :label => t('call_forwards.form.call_forward_case_id.label'), :hint => conditional_hint('call_forwards.form.call_forward_case_id.hint'), :include_blank => false, :autofocus => true
= f.input :timeout, :label => t('call_forwards.form.timeout.label'), :hint => conditional_hint('call_forwards.form.timeout.hint')
= f.input :call_forwarding_destination , :as => :select, :collection => @call_forwarding_destinations, :label => t('call_forwards.form.call_forwarding_destination.label'), :hint => conditional_hint('call_forwards.form.call_forwarding_destination.hint'), :include_blank => false
@@ -9,7 +9,7 @@
= f.input :source, :label => t('call_forwards.form.source.label'), :hint => conditional_hint('call_forwards.form.source.hint')
- if GuiFunction.display?('depth_field_in_call_forward_form', current_user)
- = f.input :depth, :collection => 1..MAX_CALL_FORWARD_DEPTH, :label => t('call_forwards.form.depth.label'), :hint => conditional_hint('call_forwards.form.depth.hint')
+ = f.input :depth, :collection => 1..GsParameter.get('MAX_CALL_FORWARD_DEPTH'), :label => t('call_forwards.form.depth.label'), :hint => conditional_hint('call_forwards.form.depth.hint')
- else
= f.hidden_field :depth
= f.input :active, :label => t('call_forwards.form.active.label'), :hint => conditional_hint('call_forwards.form.active.hint')
diff --git a/app/views/call_forwards/_index_core.html.haml b/app/views/call_forwards/_index_core.html.haml
index 7733855..27ad86f 100644
--- a/app/views/call_forwards/_index_core.html.haml
+++ b/app/views/call_forwards/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
- if !@phone_number
%th= t('call_forwards.index.phone_number_id')
@@ -10,9 +10,9 @@
%th= t('call_forwards.index.depth')
%th= t('call_forwards.index.active')
- - reset_cycle
+
- for call_forward in call_forwards
- %tr{:class => cycle('odd', 'even')}
+ %tr
- if !@phone_number
%td= call_forward.phone_number
%td= t("call_forward_cases.#{call_forward.call_forward_case.value}")
diff --git a/app/views/call_forwards/edit.html.haml b/app/views/call_forwards/edit.html.haml
index 5fa9dcd..f55052b 100644
--- a/app/views/call_forwards/edit.html.haml
+++ b/app/views/call_forwards/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("call_forwards.edit.page_title", :resource => " for phone number #{@phone_number}" )
+- content_for :title, t("call_forwards.edit.page_title", :resource => " for phone number #{@phone_number}" )
= render "form" \ No newline at end of file
diff --git a/app/views/call_forwards/index.html.haml b/app/views/call_forwards/index.html.haml
index 93d64f2..91b923a 100644
--- a/app/views/call_forwards/index.html.haml
+++ b/app/views/call_forwards/index.html.haml
@@ -1,4 +1,4 @@
-- title t("call_forwards.index.page_title")
+- content_for :title, t("call_forwards.index.page_title")
- if @call_forwards.count > 0
= render "index_core", :call_forwards => @call_forwards
diff --git a/app/views/call_forwards/new.html.haml b/app/views/call_forwards/new.html.haml
index 960a9e6..bb0c983 100644
--- a/app/views/call_forwards/new.html.haml
+++ b/app/views/call_forwards/new.html.haml
@@ -1,3 +1,3 @@
-- title t("call_forwards.new.page_title")
+- content_for :title, t("call_forwards.new.page_title")
= render "form"
diff --git a/app/views/call_forwards/show.html.haml b/app/views/call_forwards/show.html.haml
index 6d1a0c6..c2187b1 100644
--- a/app/views/call_forwards/show.html.haml
+++ b/app/views/call_forwards/show.html.haml
@@ -1,4 +1,4 @@
-- title t("call_forwards.show.page_title")
+- content_for :title, t("call_forwards.show.page_title")
%p
%strong= t('call_forwards.show.phone_number_id') + ":"
diff --git a/app/views/call_histories/_index_core.html.haml b/app/views/call_histories/_index_core.html.haml
index 2d7658a..f9d2150 100644
--- a/app/views/call_histories/_index_core.html.haml
+++ b/app/views/call_histories/_index_core.html.haml
@@ -1,65 +1,58 @@
-= form_tag(destroy_multiple_sip_account_call_histories_path(@sip_account), :method => :delete, :id => 'call_history_form') do
- %header.entries-nav= render :partial => "call_histories/navigation"
- .content
- %table
- - reset_cycle
- - for call_history in call_histories
- - phone_number = call_history.display_number
- - voicemail_message = call_history.voicemail_message
- - if phone_number
- - phone_book_entry = call_history.phone_book_entry_by_number(phone_number)
- %tr.call-history-entry{:class => cycle('odd', 'even')}
- %td.select_box= check_box_tag("selected_ids[]", call_history.id, false, :id => "select_item_#{call_history.id}", :class => 'select_item')
- %td.thumbnail
- - image = call_history.display_image(:small, phone_book_entry)
- - if image
- = image_tag(image, :itemprop => 'image')
- %td.time
- - if voicemail_message
- .voicemail-message
- %a{:href => sip_account_voicemail_messages_path(@sip_account, :anchor => "message_#{voicemail_message.id}")}
- = image_tag('icons/gs_envelope_16x.png', :class => 'display')
- = call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - elsif call_history.entry_type == 'forwarded'
- .call-forwarded= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - if call_history.callee_account_type.to_s.downcase == 'voicemail'
- = t("call_histories.index.voicemail")
- - else
- = call_history.destination_number
- - elsif call_history.entry_type == 'dialed'
- .call-placed= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - elsif call_history.entry_type == 'received'
- .call-received= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - elsif call_history.entry_type == 'missed'
- .call-missed= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - else
- .call-unknown
- = t("call_histories.index.#{call_history.entry_type}")
- = call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
- - if call_history.forwarding_service && call_history.entry_type != 'forwarded'
- = t("call_histories.index.forwarded_by")
- = call_history.display_auth_account_name
- %td.user
- - display_name = call_history.display_name
- - if display_name.blank?
- - display_name = phone_book_entry.to_s
- - if phone_book_entry
- %a.name{:href => phone_book_phone_book_entry_path(phone_book_entry.phone_book, phone_book_entry), :itemprop => "name"}= display_name
- - else
- .name= display_name
- .phone= phone_number
- %td.status
- - if call_history.display_duration
- .duration= call_history.display_duration
- - else
- .disposition= t("call_histories.call_results.#{call_history.result}")
- %td.actions
- - if @sip_account.registration && can?(:call, call_history)
- = link_to t('call_histories.index.actions.call'), call_sip_account_call_history_path(@sip_account, call_history), :method => :put
- %td.actions
- - if can? :destroy, call_history
- = link_to t('call_histories.index.actions.destroy'), sip_account_call_history_path(@sip_account, call_history), :method => :delete
+= render :partial => "call_histories/navigation"
- %footer.entries-nav= render :partial => "call_histories/navigation"
- = image_submit_tag('icons/cross-16x.png', :confirm => t("call_histories.index.actions.confirm_selected"))
- = t("call_histories.index.actions.destroy_multiple")
+%table{:class => 'table table-striped'}
+ - for call_history in call_histories
+ - phone_number = call_history.display_number
+ - voicemail_message = call_history.voicemail_message
+ - if phone_number
+ - phone_book_entry = call_history.phone_book_entry_by_number(phone_number)
+ %tr.call-history-entry
+ %td.thumbnail
+ - image = call_history.display_image(:small, phone_book_entry)
+ - if image
+ = image_tag(image, :itemprop => 'image')
+ %td.time
+ - if voicemail_message
+ .voicemail-message
+ %a{:href => sip_account_voicemail_messages_path(@sip_account, :anchor => "message_#{voicemail_message.id}")}
+ = image_tag('icons/gs_envelope_16x.png', :class => 'display')
+ = call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - elsif call_history.entry_type == 'forwarded'
+ .call-forwarded= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - if call_history.callee_account_type.to_s.downcase == 'voicemail'
+ = t("call_histories.index.voicemail")
+ - else
+ = call_history.destination_number
+ - elsif call_history.entry_type == 'dialed'
+ .call-placed= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - elsif call_history.entry_type == 'received'
+ .call-received= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - elsif call_history.entry_type == 'missed'
+ .call-missed= call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - else
+ .call-unknown
+ = t("call_histories.index.#{call_history.entry_type}")
+ = call_history.display_call_date(t("call_histories.index.date_format"), t("call_histories.index.date_today_format"))
+ - if call_history.forwarding_service && call_history.entry_type != 'forwarded'
+ = t("call_histories.index.forwarded_by")
+ = call_history.display_auth_account_name
+ %td.user
+ - display_name = call_history.display_name
+ - if display_name.blank?
+ - display_name = phone_book_entry.to_s
+ - if phone_book_entry
+ %a.name{:href => phone_book_phone_book_entry_path(phone_book_entry.phone_book, phone_book_entry), :itemprop => "name"}= display_name
+ - else
+ .name= display_name
+ .phone= phone_number
+ %td.status
+ - if call_history.display_duration
+ .duration= call_history.display_duration
+ - else
+ .disposition= t("call_histories.call_results.#{call_history.result}")
+ %td.actions
+ - if @sip_account.registration && can?(:call, call_history)
+ = link_to t('call_histories.index.actions.call'), call_sip_account_call_history_path(@sip_account, call_history), :method => :put
+ %td.actions
+ - if can? :destroy, call_history
+ = link_to t('call_histories.index.actions.destroy'), sip_account_call_history_path(@sip_account, call_history), :method => :delete
diff --git a/app/views/call_histories/_navigation.html.haml b/app/views/call_histories/_navigation.html.haml
index a1999d9..d72ad64 100644
--- a/app/views/call_histories/_navigation.html.haml
+++ b/app/views/call_histories/_navigation.html.haml
@@ -1,11 +1,14 @@
-%nav
- %ol.abc
- %li
- %a{ :href => "?type=" }= t("call_histories.index.navigation.all", :calls => @calls_count)
- %a{ :href => "?type=missed" }= t("call_histories.index.navigation.missed", :calls => @calls_missed_count)
- %a{ :href => "?type=received" }= t("call_histories.index.navigation.received", :calls => @calls_received_count)
- %a{ :href => "?type=dialed" }= t("call_histories.index.navigation.dialed", :calls => @calls_dialed_count)
- %a{ :href => "?type=forwarded" }= t("call_histories.index.navigation.forwarded", :calls => @calls_forwarded_count)
+%ul{:class => 'nav nav-pills'}
+ %li
+ %a{ :href => "?type=" }= t("call_histories.index.navigation.all", :calls => @calls_count)
+ %li
+ %a{ :href => "?type=missed" }= t("call_histories.index.navigation.missed", :calls => @calls_missed_count)
+ %li
+ %a{ :href => "?type=received" }= t("call_histories.index.navigation.received", :calls => @calls_received_count)
+ %li
+ %a{ :href => "?type=dialed" }= t("call_histories.index.navigation.dialed", :calls => @calls_dialed_count)
+ %li
+ %a{ :href => "?type=forwarded" }= t("call_histories.index.navigation.forwarded", :calls => @calls_forwarded_count)
-.pagination
- = will_paginate @call_histories
+/ .pagination
+/ = will_paginate @call_histories
diff --git a/app/views/call_histories/index.html.haml b/app/views/call_histories/index.html.haml
index adf6838..a939387 100644
--- a/app/views/call_histories/index.html.haml
+++ b/app/views/call_histories/index.html.haml
@@ -1,6 +1,6 @@
- if @type
- - title t("call_histories.index.page_title_#{@type}")
+ - content_for :title, t("call_histories.index.page_title_#{@type}")
- else
- - title t("call_histories.index.page_title")
+ - content_for :title, t("call_histories.index.page_title")
= render "index_core", :call_histories => @call_histories
diff --git a/app/views/call_routes/_form.html.haml b/app/views/call_routes/_form.html.haml
new file mode 100644
index 0000000..1415852
--- /dev/null
+++ b/app/views/call_routes/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@call_route) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('call_routes.form.submit') \ No newline at end of file
diff --git a/app/views/call_routes/_form_core.html.haml b/app/views/call_routes/_form_core.html.haml
new file mode 100644
index 0000000..b64d660
--- /dev/null
+++ b/app/views/call_routes/_form_core.html.haml
@@ -0,0 +1,5 @@
+.inputs
+ = f.input :routing_table, :collection => CallRoute::ROUTING_TABLES, :label => t('call_routes.form.table.label'), :hint => conditional_hint('call_routes.form.table.hint'), :include_blank => false, :autofocus => true
+ = f.input :name, :label => t('call_routes.form.name.label'), :hint => conditional_hint('call_routes.form.name.hint')
+ = f.input :endpoint_type, :label => t('call_routes.form.endpoint_type.label'), :hint => conditional_hint('call_routes.form.endpoint_type.hint')
+ = f.input :endpoint_id, :label => t('call_routes.form.endpoint_id.label'), :hint => conditional_hint('call_routes.form.endpoint_id.hint')
diff --git a/app/views/call_routes/_index_core.html.haml b/app/views/call_routes/_index_core.html.haml
new file mode 100644
index 0000000..5dc7c21
--- /dev/null
+++ b/app/views/call_routes/_index_core.html.haml
@@ -0,0 +1,21 @@
+- cache(['call_routes_table', call_routes.count, call_routes.reorder(:updated_at).last]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th= t('call_routes.index.name')
+ %th= t('route_elements.index.pattern')
+ %th= t('call_routes.index.endpoint_type')
+ %th{:colspan => '3'}
+
+ - for call_route in call_routes
+ - cache(['call_route_single_table_row', call_route, call_routes.count]) do
+ %tr
+ %td= call_route.name
+ %td
+ - if call_route.route_elements.any?
+ = call_route.route_elements.first.pattern
+ - if call_route.route_elements.count > 1
+ = ', ...'
+ - else
+ = '-'
+ %td= call_route.endpoint_type
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => call_route} \ No newline at end of file
diff --git a/app/views/call_routes/edit.html.haml b/app/views/call_routes/edit.html.haml
new file mode 100644
index 0000000..6048200
--- /dev/null
+++ b/app/views/call_routes/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("call_routes.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/call_routes/index.html.haml b/app/views/call_routes/index.html.haml
new file mode 100644
index 0000000..bd4468c
--- /dev/null
+++ b/app/views/call_routes/index.html.haml
@@ -0,0 +1,11 @@
+- content_for :title, t("call_routes.index.page_title")
+
+- if @call_routes && @call_routes.count > 0
+ %table{:class => 'table table-striped'}
+ - @routing_tables.each do |routing_table|
+ %tr
+ %td{:colspan => 3}
+ %h3= routing_table
+ = render "index_core", :call_routes => @call_routes.where(:routing_table => routing_table)
+
+= render :partial => 'shared/create_link', :locals => {:child_class => CallRoute}
diff --git a/app/views/call_routes/new.html.haml b/app/views/call_routes/new.html.haml
new file mode 100644
index 0000000..28aead9
--- /dev/null
+++ b/app/views/call_routes/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("call_routes.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/call_routes/show.html.haml b/app/views/call_routes/show.html.haml
new file mode 100644
index 0000000..70fe13e
--- /dev/null
+++ b/app/views/call_routes/show.html.haml
@@ -0,0 +1,22 @@
+- content_for :title, t("call_routes.show.page_title")
+
+%p
+ %strong= t('call_routes.show.table') + ":"
+ = @call_route.routing_table
+%p
+ %strong= t('call_routes.show.name') + ":"
+ = @call_route.name
+%p
+ %strong= t('call_routes.show.endpoint_type') + ":"
+ = @call_route.endpoint_type
+%p
+ %strong= t('call_routes.show.endpoint_id') + ":"
+ = @call_route.endpoint_id
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @call_route }
+
+%h3= t('route_elements.index.page_title')
+- if @call_route.route_elements && @call_route.route_elements.count > 0
+ = render "route_elements/index_core", :route_elements => @call_route.route_elements
+
+= render :partial => 'shared/create_link', :locals => { :parent => @call_route, :child_class => RouteElement }
diff --git a/app/views/calls/_index_core.html.haml b/app/views/calls/_index_core.html.haml
index ddd0650..09b7da6 100644
--- a/app/views/calls/_index_core.html.haml
+++ b/app/views/calls/_index_core.html.haml
@@ -1,9 +1,9 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('calls.index.uuid')
- - reset_cycle
+
- for call in @calls
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td
= call.uuid
diff --git a/app/views/calls/index.html.haml b/app/views/calls/index.html.haml
index 4ea60a6..be678cd 100644
--- a/app/views/calls/index.html.haml
+++ b/app/views/calls/index.html.haml
@@ -1,4 +1,4 @@
-- title t("calls.index.page_title")
+- content_for :title, t("calls.index.page_title")
- if @calls.count > 0
= render "index_core", :calls => @calls
diff --git a/app/views/callthroughs/_form_core.html.haml b/app/views/callthroughs/_form_core.html.haml
index 1f137d9..cf05e06 100644
--- a/app/views/callthroughs/_form_core.html.haml
+++ b/app/views/callthroughs/_form_core.html.haml
@@ -15,7 +15,7 @@
= f.simple_fields_for :access_authorizations do |access_authorization|
= render "access_authorizations/form_core", :f => access_authorization
- - if CALLTHROUGH_HAS_WHITELISTS == true
+ - if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
- if @callthrough && @callthrough.whitelists.size > 0
%h2= t('callthroughs.form.whitelists.label')
- if !t('callthroughs.form.whitelists.hint').blank?
diff --git a/app/views/callthroughs/_index_core.html.haml b/app/views/callthroughs/_index_core.html.haml
index f1802d4..d1c171b 100644
--- a/app/views/callthroughs/_index_core.html.haml
+++ b/app/views/callthroughs/_index_core.html.haml
@@ -1,17 +1,17 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('callthroughs.index.name')
%th= t('callthroughs.index.phone_numbers')
%th= t('callthroughs.index.access_authorized_phone_numbers')
- - if CALLTHROUGH_HAS_WHITELISTS == true
+ - if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
%th= t('callthroughs.index.whitelist_phone_numbers')
- - reset_cycle
+
- for callthrough in callthroughs
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= callthrough.name
%td=render 'phone_numbers/listing', :phone_numbers => callthrough.phone_numbers
%td=render 'phone_numbers/listing', :phone_numbers => callthrough.access_authorization_phone_numbers
- - if CALLTHROUGH_HAS_WHITELISTS == true
+ - if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
%td=render 'phone_numbers/listing', :phone_numbers => callthrough.whitelisted_phone_numbers
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => callthrough.tenant, :child => callthrough} \ No newline at end of file
diff --git a/app/views/callthroughs/edit.html.haml b/app/views/callthroughs/edit.html.haml
index 44fe17e..26fd026 100644
--- a/app/views/callthroughs/edit.html.haml
+++ b/app/views/callthroughs/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("callthroughs.edit.page_title")
+- content_for :title, t("callthroughs.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/callthroughs/index.html.haml b/app/views/callthroughs/index.html.haml
index c595351..bb3ab63 100644
--- a/app/views/callthroughs/index.html.haml
+++ b/app/views/callthroughs/index.html.haml
@@ -1,4 +1,4 @@
-- title t("callthroughs.index.page_title")
+- content_for :title, t("callthroughs.index.page_title")
- if @callthroughs.count > 0
= render "index_core", :callthroughs => @callthroughs
diff --git a/app/views/callthroughs/new.html.haml b/app/views/callthroughs/new.html.haml
index ff47c1c..deabb71 100644
--- a/app/views/callthroughs/new.html.haml
+++ b/app/views/callthroughs/new.html.haml
@@ -1,3 +1,3 @@
-- title t("callthroughs.new.page_title")
+- content_for :title, t("callthroughs.new.page_title")
= render "form"
diff --git a/app/views/callthroughs/show.html.haml b/app/views/callthroughs/show.html.haml
index 55bd6eb..da1a676 100644
--- a/app/views/callthroughs/show.html.haml
+++ b/app/views/callthroughs/show.html.haml
@@ -1,4 +1,4 @@
-- title t("callthroughs.show.page_title")
+- content_for :title, t("callthroughs.show.page_title")
%p
%strong= t('callthroughs.show.name') + ":"
@@ -19,7 +19,7 @@
%br
= render :partial => 'shared/create_link', :locals => {:parent => @callthrough, :child_class => AccessAuthorization}
-- if CALLTHROUGH_HAS_WHITELISTS == true
+- if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
%h2= t('callthroughs.form.whitelists.label')
- if @callthrough.whitelisted_phone_numbers.count > 0
= render 'whitelists/index_core', :whitelists => @callthrough.whitelists
diff --git a/app/views/conference_invitees/_index_core.html.haml b/app/views/conference_invitees/_index_core.html.haml
index f84af7d..1d6ab2e 100644
--- a/app/views/conference_invitees/_index_core.html.haml
+++ b/app/views/conference_invitees/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('conference_invitees.index.phone_book_entry_id')
%th= t('conference_invitees.index.phone_number')
@@ -6,9 +6,9 @@
%th= t('conference_invitees.index.speaker')
%th= t('conference_invitees.index.moderator')
- - reset_cycle
+
- for conference_invitee in conference_invitees
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= conference_invitee.phone_book_entry || '-'
%td= conference_invitee.phone_number
%td= conference_invitee.pin
diff --git a/app/views/conference_invitees/edit.html.haml b/app/views/conference_invitees/edit.html.haml
index ce90bbe..24c843f 100644
--- a/app/views/conference_invitees/edit.html.haml
+++ b/app/views/conference_invitees/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("conference_invitees.edit.page_title")
+- content_for :title, t("conference_invitees.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/conference_invitees/index.html.haml b/app/views/conference_invitees/index.html.haml
index 2a0c26c..846be44 100644
--- a/app/views/conference_invitees/index.html.haml
+++ b/app/views/conference_invitees/index.html.haml
@@ -1,4 +1,4 @@
-- title t("conference_invitees.index.page_title")
+- content_for :title, t("conference_invitees.index.page_title")
- if @conference_invitees.count > 0
= render "index_core", :conference_invitees => @conference_invitees
diff --git a/app/views/conference_invitees/new.html.haml b/app/views/conference_invitees/new.html.haml
index 780494e..1957d5d 100644
--- a/app/views/conference_invitees/new.html.haml
+++ b/app/views/conference_invitees/new.html.haml
@@ -1,3 +1,3 @@
-- title t("conference_invitees.new.page_title")
+- content_for :title, t("conference_invitees.new.page_title")
= render "form"
diff --git a/app/views/conference_invitees/show.html.haml b/app/views/conference_invitees/show.html.haml
index 57c5627..12fcbd1 100644
--- a/app/views/conference_invitees/show.html.haml
+++ b/app/views/conference_invitees/show.html.haml
@@ -1,4 +1,4 @@
-- title t("conference_invitees.show.page_title")
+- content_for :title, t("conference_invitees.show.page_title")
%p
%strong= t('conference_invitees.show.conference_id') + ":"
diff --git a/app/views/conferences/_form_core.html.haml b/app/views/conferences/_form_core.html.haml
index 04754de..f8d6c8e 100644
--- a/app/views/conferences/_form_core.html.haml
+++ b/app/views/conferences/_form_core.html.haml
@@ -5,7 +5,7 @@
= f.input :end, :label => t('conferences.form.end.label'), :hint => conditional_hint('conferences.form.end.hint'), :include_blank => true, :start_year => Time.now.year, :end_year => Time.now.year + 2
= f.input :description, :label => t('conferences.form.description.label'), :hint => conditional_hint('conferences.form.description.hint')
= f.input :pin, :label => t('conferences.form.pin.label'), :hint => conditional_hint('conferences.form.pin.hint')
- = f.input :max_members, :collection => 1..MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE, :include_blank => false, :label => t('conferences.form.max_members.label'), :hint => conditional_hint('conferences.form.max_members.hint')
+ = f.input :max_members, :collection => 1..GsParameter.get('MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE'), :include_blank => false, :label => t('conferences.form.max_members.label'), :hint => conditional_hint('conferences.form.max_members.hint')
= f.input :open_for_anybody, :label => t('conferences.form.open_for_anybody.label'), :hint => conditional_hint('conferences.form.open_for_anybody.hint')
= f.input :announce_new_member_by_name, :label => t('conferences.form.announce_new_member_by_name.label'), :hint => conditional_hint('conferences.form.announce_new_member_by_name.hint')
= f.input :announce_left_member_by_name, :label => t('conferences.form.announce_left_member_by_name.label'), :hint => conditional_hint('conferences.form.announce_left_member_by_name.hint') \ No newline at end of file
diff --git a/app/views/conferences/_index_core.html.haml b/app/views/conferences/_index_core.html.haml
index 4073e83..50ea1c8 100644
--- a/app/views/conferences/_index_core.html.haml
+++ b/app/views/conferences/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('conferences.index.name')
- if !conferences.respond_to?('where') || conferences.where(:start => nil).where(:end => nil).count != conferences.count
@@ -11,10 +11,10 @@
%th= t('conferences.index.number_of_invitees')
%th= t('conferences.index.flags')
- - reset_cycle
+
- for conference in conferences
- parent = conference.conferenceable
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= conference.name
- if !conferences.respond_to?('where') || conferences.where(:start => nil).where(:end => nil).count != conferences.count
%td
diff --git a/app/views/conferences/edit.html.haml b/app/views/conferences/edit.html.haml
index bc190e7..d5ec058 100644
--- a/app/views/conferences/edit.html.haml
+++ b/app/views/conferences/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("conferences.edit.page_title")
+- content_for :title, t("conferences.edit.page_title")
= render "form"
diff --git a/app/views/conferences/index.html.haml b/app/views/conferences/index.html.haml
index 0324acd..08f5cc1 100644
--- a/app/views/conferences/index.html.haml
+++ b/app/views/conferences/index.html.haml
@@ -1,4 +1,4 @@
-- title t("conferences.index.page_title")
+- content_for :title, t("conferences.index.page_title")
- if @conferences.count > 0
= render "index_core", :conferences => @conferences
diff --git a/app/views/conferences/new.html.haml b/app/views/conferences/new.html.haml
index 102f6a9..2dcb125 100644
--- a/app/views/conferences/new.html.haml
+++ b/app/views/conferences/new.html.haml
@@ -1,3 +1,3 @@
-- title t("conferences.new.page_title")
+- content_for :title, t("conferences.new.page_title")
= render "form"
diff --git a/app/views/conferences/show.html.haml b/app/views/conferences/show.html.haml
index 10ebaed..0afa822 100644
--- a/app/views/conferences/show.html.haml
+++ b/app/views/conferences/show.html.haml
@@ -1,4 +1,4 @@
-- title t("conferences.show.page_title")
+- content_for :title, t("conferences.show.page_title")
%p
%strong= t('conferences.show.name') + ":"
diff --git a/app/views/config_polycom/_call_history.xml.haml b/app/views/config_polycom/_call_history.xml.haml
index 7d23edd..4ecb8fe 100644
--- a/app/views/config_polycom/_call_history.xml.haml
+++ b/app/views/config_polycom/_call_history.xml.haml
@@ -3,7 +3,7 @@
%head
%title= @phone_xml_object[:title]
%body
- %table{ :border => 0 }
+ %table{:class => 'table table-striped'}{ :border => 0 }
%tbody
- @phone_xml_object[:entries].each do |entry|
%tr
diff --git a/app/views/config_polycom/_phone_book.xml.haml b/app/views/config_polycom/_phone_book.xml.haml
index 1066695..3867f41 100644
--- a/app/views/config_polycom/_phone_book.xml.haml
+++ b/app/views/config_polycom/_phone_book.xml.haml
@@ -3,7 +3,7 @@
%head
%title= @phone_xml_object[:title]
%body
- %table{ :border => 0 }
+ %table{:class => 'table table-striped'}{ :border => 0 }
%tbody
- @phone_xml_object[:entries].each do |entry|
%tr
diff --git a/app/views/config_snom/show.xml.haml b/app/views/config_snom/show.xml.haml
index d9953c5..5f53802 100644
--- a/app/views/config_snom/show.xml.haml
+++ b/app/views/config_snom/show.xml.haml
@@ -48,8 +48,8 @@
%use_proxy_number_guessing{:perm => 'RW'}= 'off'
%guess_number{:perm => 'RW'}= 'off'
%guess_start_length{:perm => 'RW'}= '3'
- %ieee8021x_eap_md5_username{:perm => 'RW'}= PROVISIONING_IEEE8021X_EAP_USERNAME
- %ieee8021x_eap_md5_password{:perm => 'RW'}= PROVISIONING_IEEE8021X_EAP_PASSWORD
+ %ieee8021x_eap_md5_username{:perm => 'RW'}= GsParameter.get('PROVISIONING_IEEE8021X_EAP_USERNAME')
+ %ieee8021x_eap_md5_password{:perm => 'RW'}= GsParameter.get('PROVISIONING_IEEE8021X_EAP_PASSWORD')
- 0.upto(9) do |ringer_idx|
%internal_ringer_text{:idx => ringer_idx, :perm => 'RW'}= "Ringer#{(ringer_idx+1)}"
@@ -68,6 +68,11 @@
%dkey_conf{:perm => 'RW'}= @dkeys[:conf]
%dkey_redial{:perm => 'RW'}= @dkeys[:redial]
%dkey_directory{:perm => 'RW'}= @dkeys[:directory]
+ %dkey_touch_idle_adr_book{:perm => 'RW'}= @dkeys[:touch_idle_adr_book]
+ %dkey_touch_idle_list_missed{:perm => 'RW'}= @dkeys[:touch_idle_list_missed]
+ %dkey_touch_idle_list_taken{:perm => 'RW'}= @dkeys[:touch_idle_list_taken]
+ %dkey_touch_idle_redial{:perm => 'RW'}= @dkeys[:touch_idle_redial]
+ %dkey_touch_idle_dialog{:perm => 'RW'}= @dkeys[:touch_idle_dialog]
%idle_ok_key_action{:perm => 'RW'}= @dkeys[:idle_ok]
%idle_cancel_key_action{:perm => 'RW'}= @dkeys[:idle_cancel]
@@ -76,6 +81,29 @@
%idle_left_key_action{:perm => 'RW'}= @dkeys[:idle_left]
%idle_right_key_action{:perm => 'RW'}= @dkeys[:idle_right]
+ / Display
+ %backlight{:perm => 'RW'}= '15'
+ %backlight_idle{:perm => 'RW'}= '0'
+ %dim_timer{:perm => 'RW'}= '300'
+
+ - if @phone.phone_model.name == 'Snom 870'
+ / Snom 870 idle icons
+ %idle_icon_01{:perm => 'RW'}= '9'
+ %idle_icon_02{:perm => 'RW'}= '20'
+ %idle_icon_03{:perm => 'RW'}= '4'
+ %idle_icon_04{:perm => 'RW'}= '-1'
+ %idle_icon_05{:perm => 'RW'}= '6'
+ %idle_icon_06{:perm => 'RW'}= '-1'
+ %idle_icon_07{:perm => 'RW'}= '-1'
+ %idle_icon_08{:perm => 'RW'}= '-1'
+ %idle_icon_09{:perm => 'RW'}= '-1'
+ %idle_icon_10{:perm => 'RW'}= '-1'
+ %idle_icon_11{:perm => 'RW'}= '15'
+ %idle_icon_12{:perm => 'RW'}= '-1'
+ %idle_icon_13{:perm => 'RW'}= '-1'
+ %idle_icon_14{:perm => 'RW'}= '13'
+ %idle_icon_15{:perm => 'RW'}= '12'
+
!= "\<!-- sip accounts: #{@sip_accounts.count} --\>"
- @sip_accounts.each_with_index do |sip_account, array_index|
- index = array_index + 1
@@ -148,4 +176,5 @@
%uploads
- if @state_settings_url
+ / Phone menu
%file{:url => @state_settings_url, :type => "gui_xml_state_settings"}
diff --git a/app/views/config_snom/state_settings.xml.haml b/app/views/config_snom/state_settings.xml.haml
index ac0e872..6be1efc 100644
--- a/app/views/config_snom/state_settings.xml.haml
+++ b/app/views/config_snom/state_settings.xml.haml
@@ -1,5 +1,5 @@
!!! XML
-%SnomIPPhoneMenu{:state => 'relevant', :title => "Gemeinschaft #{GEMEINSCHAFT_VERSION}"}
+%SnomIPPhoneMenu{:state => 'relevant', :title => "Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}"}
%MenuItem{:name => '$(lang:menu100_phone_book)'}
%URL= "#{@base_url}/#{@sip_account_ids.first}/phone_book.xml"
%Menu{:name => '$(lang:menu100_call_lists)'}
diff --git a/app/views/fax_accounts/_index_core.html.haml b/app/views/fax_accounts/_index_core.html.haml
index 50dc2eb..5a04bf0 100644
--- a/app/views/fax_accounts/_index_core.html.haml
+++ b/app/views/fax_accounts/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('fax_accounts.index.name')
%th
@@ -13,9 +13,9 @@
%small
= t('fax_accounts.index.last_update')
- - reset_cycle
+
- for fax_account in fax_accounts
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= truncate(fax_account.name, :length => 15)
%td
=render 'phone_numbers/listing', :phone_numbers => fax_account.phone_numbers.order(:number)
diff --git a/app/views/fax_accounts/edit.html.haml b/app/views/fax_accounts/edit.html.haml
index 86f664d..3cdc655 100644
--- a/app/views/fax_accounts/edit.html.haml
+++ b/app/views/fax_accounts/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("fax_accounts.edit.page_title")
+- content_for :title, t("fax_accounts.edit.page_title")
= render "form"
diff --git a/app/views/fax_accounts/index.html.haml b/app/views/fax_accounts/index.html.haml
index 309a10d..9710454 100644
--- a/app/views/fax_accounts/index.html.haml
+++ b/app/views/fax_accounts/index.html.haml
@@ -1,4 +1,4 @@
-- title t("fax_accounts.index.page_title")
+- content_for :title, t("fax_accounts.index.page_title")
- if @fax_accounts.count > 0
= render "index_core", {:fax_accounts => @fax_accounts, :fax_accountable => @parent}
diff --git a/app/views/fax_accounts/new.html.haml b/app/views/fax_accounts/new.html.haml
index 9a67100..eff9347 100644
--- a/app/views/fax_accounts/new.html.haml
+++ b/app/views/fax_accounts/new.html.haml
@@ -1,3 +1,3 @@
-- title t("fax_accounts.new.page_title")
+- content_for :title, t("fax_accounts.new.page_title")
= render "form"
diff --git a/app/views/fax_accounts/show.html.haml b/app/views/fax_accounts/show.html.haml
index 95fb7b2..1a32121 100644
--- a/app/views/fax_accounts/show.html.haml
+++ b/app/views/fax_accounts/show.html.haml
@@ -1,4 +1,4 @@
-- title t("fax_accounts.show.page_title")
+- content_for :title, t("fax_accounts.show.page_title")
%p
%strong= t('fax_accounts.show.name') + ":"
diff --git a/app/views/fax_documents/_index_core.html.haml b/app/views/fax_documents/_index_core.html.haml
index 4e15509..1265716 100644
--- a/app/views/fax_documents/_index_core.html.haml
+++ b/app/views/fax_documents/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('fax_documents.index.sent_at')
%th= t('fax_documents.index.state')
@@ -9,9 +9,9 @@
= t('fax_documents.index.remote_station_id')
%th= t('fax_documents.index.thumbnails')
- - reset_cycle
+
- for fax_document in fax_documents
- %tr{:class => cycle('odd', 'even'), :id => "fax_document_#{fax_document.id}"}
+ %tr{:id => "fax_document_#{fax_document.id}"}
- if fax_document.sent_at
%td= "#{fax_document.inbound ? '&#8680;' : '&#8678;'} #{fax_document.sent_at}".html_safe
%td= t("fax_documents.states.#{fax_document.state}")
diff --git a/app/views/fax_documents/edit.html.haml b/app/views/fax_documents/edit.html.haml
index 5da92c6..239bf8b 100644
--- a/app/views/fax_documents/edit.html.haml
+++ b/app/views/fax_documents/edit.html.haml
@@ -1,4 +1,4 @@
-- title t("fax_documents.edit.page_title")
+- content_for :title, t("fax_documents.edit.page_title")
= render "form"
diff --git a/app/views/fax_documents/index.html.haml b/app/views/fax_documents/index.html.haml
index 11199dd..33c697c 100644
--- a/app/views/fax_documents/index.html.haml
+++ b/app/views/fax_documents/index.html.haml
@@ -1,4 +1,4 @@
-- title t("fax_documents.index.page_title")
+- content_for :title, t("fax_documents.index.page_title")
= render "index_core", :fax_documents => @fax_documents
diff --git a/app/views/fax_documents/new.html.haml b/app/views/fax_documents/new.html.haml
index be02860..8884418 100644
--- a/app/views/fax_documents/new.html.haml
+++ b/app/views/fax_documents/new.html.haml
@@ -1,3 +1,3 @@
-- title t("fax_documents.new.page_title")
+- content_for :title, t("fax_documents.new.page_title")
= render "form"
diff --git a/app/views/fax_documents/show.html.haml b/app/views/fax_documents/show.html.haml
index 4703e1d..41d3bff 100644
--- a/app/views/fax_documents/show.html.haml
+++ b/app/views/fax_documents/show.html.haml
@@ -1,4 +1,4 @@
-- title t("fax_documents.show.page_title")
+- content_for :title, t("fax_documents.show.page_title")
- child = @fax_document
- parent = @fax_document.fax_account
diff --git a/app/views/freeswitch_voicemail_msgs/_index_core.html.haml b/app/views/freeswitch_voicemail_msgs/_index_core.html.haml
index 58d9944..2ada034 100644
--- a/app/views/freeswitch_voicemail_msgs/_index_core.html.haml
+++ b/app/views/freeswitch_voicemail_msgs/_index_core.html.haml
@@ -1,12 +1,12 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('freeswitch_voicemail_msgs.index.created_epoch')
%th= t('freeswitch_voicemail_msgs.index.message_len')
%th= t('freeswitch_voicemail_msgs.index.file_path')
- - reset_cycle
+
- for freeswitch_voicemail_msg in freeswitch_voicemail_msgs
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= freeswitch_voicemail_msg.created_epoch
%td= freeswitch_voicemail_msg.message_len
%td= freeswitch_voicemail_msg.file_path \ No newline at end of file
diff --git a/app/views/freeswitch_voicemail_msgs/index.html.haml b/app/views/freeswitch_voicemail_msgs/index.html.haml
index 5083c6f..77977c3 100644
--- a/app/views/freeswitch_voicemail_msgs/index.html.haml
+++ b/app/views/freeswitch_voicemail_msgs/index.html.haml
@@ -1,3 +1,3 @@
-- title t("freeswitch_voicemail_msgs.index.page_title")
+- content_for :title, t("freeswitch_voicemail_msgs.index.page_title")
= render "index_core", :freeswitch_voicemail_msgs => @freeswitch_voicemail_msgs \ No newline at end of file
diff --git a/app/views/gateway_parameters/_form.html.haml b/app/views/gateway_parameters/_form.html.haml
new file mode 100644
index 0000000..79342d2
--- /dev/null
+++ b/app/views/gateway_parameters/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for([@gateway, @gateway_parameter]) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('gateway_parameters.form.submit') \ No newline at end of file
diff --git a/app/views/gateway_parameters/_form_core.html.haml b/app/views/gateway_parameters/_form_core.html.haml
new file mode 100644
index 0000000..206645d
--- /dev/null
+++ b/app/views/gateway_parameters/_form_core.html.haml
@@ -0,0 +1,5 @@
+.inputs
+ = f.input :name, :label => t('gateway_parameters.form.name.label'), :hint => conditional_hint('gateway_parameters.form.name.hint'), :autofocus => true
+ = f.input :value, :label => t('gateway_parameters.form.value.label'), :hint => conditional_hint('gateway_parameters.form.value.hint')
+ = f.input :class_type, :collection => GatewayParameter::CLASS_TYPES, :label => t('gateway_parameters.form.class_type.label'), :hint => conditional_hint('gateway_parameters.form.class_type.hint'), :include_blank => false
+ = f.input :description, :label => t('gateway_parameters.form.description.label'), :hint => conditional_hint('gateway_parameters.form.description.hint')
diff --git a/app/views/gateway_parameters/_index_core.html.haml b/app/views/gateway_parameters/_index_core.html.haml
new file mode 100644
index 0000000..0d00aaf
--- /dev/null
+++ b/app/views/gateway_parameters/_index_core.html.haml
@@ -0,0 +1,13 @@
+%table{:class => 'table table-striped'}
+ %tr
+ %th= t('gateway_parameters.index.name')
+ %th= t('gateway_parameters.index.value')
+ %th= t('gateway_parameters.index.description')
+
+
+ - for gateway_parameter in gateway_parameters
+ %tr
+ %td= gateway_parameter.name
+ %td= gateway_parameter.value
+ %td= gateway_parameter.description
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => gateway_parameter.gateway, :child => gateway_parameter}
diff --git a/app/views/gateway_parameters/edit.html.haml b/app/views/gateway_parameters/edit.html.haml
new file mode 100644
index 0000000..67fb831
--- /dev/null
+++ b/app/views/gateway_parameters/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateway_parameters.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateway_parameters/index.html.haml b/app/views/gateway_parameters/index.html.haml
new file mode 100644
index 0000000..9eee4a3
--- /dev/null
+++ b/app/views/gateway_parameters/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("gateway_parameters.index.page_title")
+
+- if @gateway_parameters && @gateway_parameters.count > 0
+ = render "index_core", :gateway_parameters => @gateway_parameters
+
+= render :partial => 'shared/create_link', :locals => {:parent => @gateway, :child_class => GatewayParameter} \ No newline at end of file
diff --git a/app/views/gateway_parameters/new.html.haml b/app/views/gateway_parameters/new.html.haml
new file mode 100644
index 0000000..5899602
--- /dev/null
+++ b/app/views/gateway_parameters/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateway_parameters.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateway_parameters/show.html.haml b/app/views/gateway_parameters/show.html.haml
new file mode 100644
index 0000000..9bdad76
--- /dev/null
+++ b/app/views/gateway_parameters/show.html.haml
@@ -0,0 +1,19 @@
+- content_for :title, t("gateway_parameters.show.page_title")
+
+%p
+ %strong= t('gateway_parameters.show.gateway_id') + ":"
+ = @gateway_parameter.gateway
+%p
+ %strong= t('gateway_parameters.show.name') + ":"
+ = @gateway_parameter.name
+%p
+ %strong= t('gateway_parameters.show.value') + ":"
+ = @gateway_parameter.value
+%p
+ %strong= t('gateway_parameters.show.class_type') + ":"
+ = @gateway_parameter.class_type
+%p
+ %strong= t('gateway_parameters.show.description') + ":"
+ = @gateway_parameter.description
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @gateway, :child => @gateway_parameter } \ No newline at end of file
diff --git a/app/views/gateway_settings/_form.html.haml b/app/views/gateway_settings/_form.html.haml
new file mode 100644
index 0000000..af26d2a
--- /dev/null
+++ b/app/views/gateway_settings/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for([@gateway, @gateway_setting]) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('gateway_settings.form.submit')
diff --git a/app/views/gateway_settings/_form_core.html.haml b/app/views/gateway_settings/_form_core.html.haml
new file mode 100644
index 0000000..3e7dc49
--- /dev/null
+++ b/app/views/gateway_settings/_form_core.html.haml
@@ -0,0 +1,4 @@
+.inputs
+ = f.input :name, :collection => GatewaySetting::GATEWAY_SETTINGS['sip'].keys, :label => t('gateway_settings.form.name.label'), :hint => conditional_hint('gateway_settings.form.name.hint'), :autofocus => true, :include_blank => false
+ = f.input :value, :label => t('gateway_settings.form.value.label'), :hint => conditional_hint('gateway_settings.form.value.hint')
+ = f.input :description, :label => t('gateway_settings.form.description.label'), :hint => conditional_hint('gateway_settings.form.description.hint')
diff --git a/app/views/gateway_settings/_index_core.html.haml b/app/views/gateway_settings/_index_core.html.haml
new file mode 100644
index 0000000..ded7eb8
--- /dev/null
+++ b/app/views/gateway_settings/_index_core.html.haml
@@ -0,0 +1,13 @@
+%table{:class => 'table table-striped'}
+ %tr
+ %th= t('gateway_settings.index.name')
+ %th= t('gateway_settings.index.value')
+ %th= t('gateway_settings.index.description')
+
+
+ - for gateway_setting in gateway_settings
+ %tr
+ %td= gateway_setting.name
+ %td= gateway_setting.value
+ %td= gateway_setting.description
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => gateway_setting.gateway, :child => gateway_setting}
diff --git a/app/views/gateway_settings/edit.html.haml b/app/views/gateway_settings/edit.html.haml
new file mode 100644
index 0000000..464c36e
--- /dev/null
+++ b/app/views/gateway_settings/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateway_settings.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateway_settings/index.html.haml b/app/views/gateway_settings/index.html.haml
new file mode 100644
index 0000000..3f1400e
--- /dev/null
+++ b/app/views/gateway_settings/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("gateway_settings.index.page_title")
+
+- if @gateway_settings && @gateway_settings.count > 0
+ = render "index_core", :gateway_settings => @gateway_settings
+
+= render :partial => 'shared/create_link', :locals => {:parent => @gateway, :child_class => GatewaySetting}
diff --git a/app/views/gateway_settings/new.html.haml b/app/views/gateway_settings/new.html.haml
new file mode 100644
index 0000000..ec8c346
--- /dev/null
+++ b/app/views/gateway_settings/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateway_settings.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateway_settings/show.html.haml b/app/views/gateway_settings/show.html.haml
new file mode 100644
index 0000000..019aec4
--- /dev/null
+++ b/app/views/gateway_settings/show.html.haml
@@ -0,0 +1,19 @@
+- content_for :title, t("gateway_settings.show.page_title")
+
+%p
+ %strong= t('gateway_settings.show.gateway_id') + ":"
+ = @gateway_setting.gateway
+%p
+ %strong= t('gateway_settings.show.name') + ":"
+ = @gateway_setting.name
+%p
+ %strong= t('gateway_settings.show.value') + ":"
+ = @gateway_setting.value
+%p
+ %strong= t('gateway_settings.show.class_type') + ":"
+ = @gateway_setting.class_type
+%p
+ %strong= t('gateway_settings.show.description') + ":"
+ = @gateway_setting.description
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => {:parent => @gateway_setting.gateway, :child => @gateway_setting} \ No newline at end of file
diff --git a/app/views/gateways/_form.html.haml b/app/views/gateways/_form.html.haml
new file mode 100644
index 0000000..5f6d5dd
--- /dev/null
+++ b/app/views/gateways/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@gateway) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('gateways.form.submit') \ No newline at end of file
diff --git a/app/views/gateways/_form_core.html.haml b/app/views/gateways/_form_core.html.haml
new file mode 100644
index 0000000..13ed8b1
--- /dev/null
+++ b/app/views/gateways/_form_core.html.haml
@@ -0,0 +1,6 @@
+.inputs
+ = f.input :name, :label => t('gateways.form.name.label'), :hint => conditional_hint('gateways.form.name.hint'), :autofocus => true
+ = f.input :technology, :label => t('gateways.form.technology.label'), :hint => conditional_hint('gateways.form.technology.hint')
+ = f.input :inbound, :label => t('gateways.form.inbound.label'), :hint => conditional_hint('gateways.form.inbound.hint')
+ = f.input :outbound, :label => t('gateways.form.outbound.label'), :hint => conditional_hint('gateways.form.outbound.hint')
+ = f.input :description, :label => t('gateways.form.description.label'), :hint => conditional_hint('gateways.form.description.hint')
diff --git a/app/views/gateways/_index_core.html.haml b/app/views/gateways/_index_core.html.haml
new file mode 100644
index 0000000..0eec67f
--- /dev/null
+++ b/app/views/gateways/_index_core.html.haml
@@ -0,0 +1,19 @@
+- cache(['gateways_table', gateways.count, gateways.first, gateways.last]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th= t('gateways.index.name')
+ %th= t('gateways.index.technology')
+ %th= t('gateways.index.inbound')
+ %th= t('gateways.index.outbound')
+ %th= t('gateways.index.description')
+ %th{:colspan => '3'}
+
+ - for gateway in gateways
+ %tr
+ - cache(['gateway_single_table_row_within_tr', gateway, gateways.count]) do
+ %td= gateway.name
+ %td= gateway.technology
+ %td= gateway.inbound
+ %td= gateway.outbound
+ %td= gateway.description
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => gateway} \ No newline at end of file
diff --git a/app/views/gateways/edit.html.haml b/app/views/gateways/edit.html.haml
new file mode 100644
index 0000000..238dc3c
--- /dev/null
+++ b/app/views/gateways/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateways.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateways/index.html.haml b/app/views/gateways/index.html.haml
new file mode 100644
index 0000000..f5d3275
--- /dev/null
+++ b/app/views/gateways/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("gateways.index.page_title")
+
+- if @gateways && @gateways.count > 0
+ = render "index_core", :gateways => @gateways
+
+= render :partial => 'shared/create_link', :locals => {:child_class => Gateway} \ No newline at end of file
diff --git a/app/views/gateways/new.html.haml b/app/views/gateways/new.html.haml
new file mode 100644
index 0000000..d17ff6e
--- /dev/null
+++ b/app/views/gateways/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("gateways.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gateways/show.html.haml b/app/views/gateways/show.html.haml
new file mode 100644
index 0000000..9a3e1c4
--- /dev/null
+++ b/app/views/gateways/show.html.haml
@@ -0,0 +1,35 @@
+- content_for :title, t("gateways.show.page_title")
+
+%p
+ %strong= t('gateways.show.id') + ":"
+ = @gateway.id
+%p
+ %strong= t('gateways.show.name') + ":"
+ = @gateway.name
+%p
+ %strong= t('gateways.show.technology') + ":"
+ = @gateway.technology
+%p
+ %strong= t('gateways.show.inbound') + ":"
+ = @gateway.inbound
+%p
+ %strong= t('gateways.show.outbound') + ":"
+ = @gateway.outbound
+%p
+ %strong= t('gateways.show.description') + ":"
+ = @gateway.description
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @gateway }
+
+
+%h3= t('gateway_settings.index.page_title')
+- if @gateway.gateway_settings.any?
+ = render "gateway_settings/index_core", :gateway_settings => @gateway.gateway_settings
+ %br
+= render :partial => 'shared/create_link', :locals => { :parent => @gateway, :child_class => GatewaySetting }
+
+%h3= t('gateway_parameters.index.page_title')
+- if @gateway.gateway_parameters.any?
+ = render "gateway_parameters/index_core", :gateway_parameters => @gateway.gateway_parameters
+ %br
+= render :partial => 'shared/create_link', :locals => { :parent => @gateway, :child_class => GatewayParameter }
diff --git a/app/views/gemeinschaft_setups/new.de.html.haml b/app/views/gemeinschaft_setups/new.de.html.haml
index 5e79115..b78e278 100644
--- a/app/views/gemeinschaft_setups/new.de.html.haml
+++ b/app/views/gemeinschaft_setups/new.de.html.haml
@@ -1,4 +1,5 @@
-- title "Konfiguration einer Gemeinschaft #{GEMEINSCHAFT_VERSION} Installation"
+- content_for :title, 'Gemeinschaft 5.0'
+- content_for :meta_description, "Konfiguration einer Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')} Installation"
= simple_form_for(@gemeinschaft_setup) do |f|
= f.error_notification
@@ -20,6 +21,7 @@
= f.association :country, :label => t('gemeinschaft_setups.form.country_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.country_id.hint'), :include_blank => false
= f.association :language, :label => t('gemeinschaft_setups.form.language_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.language_id.hint'), :include_blank => false
+ = f.input :default_area_code, :label => t('gemeinschaft_setups.form.default_area_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_area_code.hint')
.actions
= f.button :submit, conditional_t('gemeinschaft_setups.form.submit') \ No newline at end of file
diff --git a/app/views/gemeinschaft_setups/new.html.haml b/app/views/gemeinschaft_setups/new.html.haml
index f5f0e81..1b97cc0 100644
--- a/app/views/gemeinschaft_setups/new.html.haml
+++ b/app/views/gemeinschaft_setups/new.html.haml
@@ -1,4 +1,5 @@
-- title "Configure a new Gemeinschaft #{GEMEINSCHAFT_VERSION} server"
+- content_for :title, 'Gemeinschaft 5.0'
+- content_for :meta_description, "Configure a new Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')} server"
= simple_form_for(@gemeinschaft_setup) do |f|
= f.error_notification
@@ -20,6 +21,7 @@
= f.association :country, :label => t('gemeinschaft_setups.form.country_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.country_id.hint'), :include_blank => false
= f.association :language, :label => t('gemeinschaft_setups.form.language_id.label'), :hint => conditional_hint('gemeinschaft_setups.form.language_id.hint'), :include_blank => false
+ = f.input :default_area_code, :label => t('gemeinschaft_setups.form.default_area_code.label'), :hint => conditional_hint('gemeinschaft_setups.form.default_area_code.hint')
.actions
= f.button :submit, conditional_t('gemeinschaft_setups.form.submit') \ No newline at end of file
diff --git a/app/views/gs_cluster_sync_log_entries/_index_core.html.haml b/app/views/gs_cluster_sync_log_entries/_index_core.html.haml
index 05cbda8..c9a3e50 100644
--- a/app/views/gs_cluster_sync_log_entries/_index_core.html.haml
+++ b/app/views/gs_cluster_sync_log_entries/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('gs_cluster_sync_log_entries.index.gs_node_id')
%th= t('gs_cluster_sync_log_entries.index.class_name')
@@ -6,9 +6,9 @@
%th= t('gs_cluster_sync_log_entries.index.content')
%th= t('gs_cluster_sync_log_entries.index.status')
- - reset_cycle
+
- for gs_cluster_sync_log_entry in gs_cluster_sync_log_entries
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= gs_cluster_sync_log_entry.gs_node_id
%td= gs_cluster_sync_log_entry.class_name
%td= gs_cluster_sync_log_entry.action
diff --git a/app/views/gs_cluster_sync_log_entries/edit.html.haml b/app/views/gs_cluster_sync_log_entries/edit.html.haml
index b0c65f3..856b91f 100644
--- a/app/views/gs_cluster_sync_log_entries/edit.html.haml
+++ b/app/views/gs_cluster_sync_log_entries/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("gs_cluster_sync_log_entries.edit.page_title")
+- content_for :title, t("gs_cluster_sync_log_entries.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gs_cluster_sync_log_entries/index.html.haml b/app/views/gs_cluster_sync_log_entries/index.html.haml
index 68be7e0..2e1b248 100644
--- a/app/views/gs_cluster_sync_log_entries/index.html.haml
+++ b/app/views/gs_cluster_sync_log_entries/index.html.haml
@@ -1,4 +1,4 @@
-- title t("gs_cluster_sync_log_entries.index.page_title")
+- content_for :title, t("gs_cluster_sync_log_entries.index.page_title")
- if @gs_cluster_sync_log_entries && @gs_cluster_sync_log_entries.count > 0
= render "index_core", :gs_cluster_sync_log_entries => @gs_cluster_sync_log_entries
diff --git a/app/views/gs_cluster_sync_log_entries/new.html.haml b/app/views/gs_cluster_sync_log_entries/new.html.haml
index 01b795c..ebe03bc 100644
--- a/app/views/gs_cluster_sync_log_entries/new.html.haml
+++ b/app/views/gs_cluster_sync_log_entries/new.html.haml
@@ -1,3 +1,3 @@
-- title t("gs_cluster_sync_log_entries.new.page_title")
+- content_for :title, t("gs_cluster_sync_log_entries.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gs_cluster_sync_log_entries/show.html.haml b/app/views/gs_cluster_sync_log_entries/show.html.haml
index 733576d..24dd3d7 100644
--- a/app/views/gs_cluster_sync_log_entries/show.html.haml
+++ b/app/views/gs_cluster_sync_log_entries/show.html.haml
@@ -1,4 +1,4 @@
-- title t("gs_cluster_sync_log_entries.show.page_title")
+- content_for :title, t("gs_cluster_sync_log_entries.show.page_title")
%p
%strong= t('gs_cluster_sync_log_entries.show.gs_node_id') + ":"
diff --git a/app/views/gs_nodes/_index_core.html.haml b/app/views/gs_nodes/_index_core.html.haml
index 72633e1..0f1a51c 100644
--- a/app/views/gs_nodes/_index_core.html.haml
+++ b/app/views/gs_nodes/_index_core.html.haml
@@ -1,4 +1,4 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('gs_nodes.index.name')
%th= t('gs_nodes.index.ip_address')
@@ -7,9 +7,9 @@
%th= t('gs_nodes.index.push_updates_to')
%th= t('gs_nodes.index.accepts_updates_from')
- - reset_cycle
+
- for gs_node in gs_nodes
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= gs_node.name
%td= gs_node.ip_address
%td= gs_node.site
diff --git a/app/views/gs_nodes/edit.html.haml b/app/views/gs_nodes/edit.html.haml
index c025b05..55180f3 100644
--- a/app/views/gs_nodes/edit.html.haml
+++ b/app/views/gs_nodes/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("gs_nodes.edit.page_title")
+- content_for :title, t("gs_nodes.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gs_nodes/index.html.haml b/app/views/gs_nodes/index.html.haml
index 4670cef..2c4ba0b 100644
--- a/app/views/gs_nodes/index.html.haml
+++ b/app/views/gs_nodes/index.html.haml
@@ -1,4 +1,4 @@
-- title t("gs_nodes.index.page_title")
+- content_for :title, t("gs_nodes.index.page_title")
- if @gs_nodes && @gs_nodes.count > 0
= render "index_core", :gs_nodes => @gs_nodes
diff --git a/app/views/gs_nodes/new.html.haml b/app/views/gs_nodes/new.html.haml
index 230ce33..8425084 100644
--- a/app/views/gs_nodes/new.html.haml
+++ b/app/views/gs_nodes/new.html.haml
@@ -1,3 +1,3 @@
-- title t("gs_nodes.new.page_title")
+- content_for :title, t("gs_nodes.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gs_nodes/show.html.haml b/app/views/gs_nodes/show.html.haml
index ca70a50..bccf785 100644
--- a/app/views/gs_nodes/show.html.haml
+++ b/app/views/gs_nodes/show.html.haml
@@ -1,4 +1,4 @@
-- title t("gs_nodes.show.page_title")
+- content_for :title, t("gs_nodes.show.page_title")
%p
%strong= t('gs_nodes.show.name') + ":"
diff --git a/app/views/gs_parameters/_form.html.haml b/app/views/gs_parameters/_form.html.haml
new file mode 100644
index 0000000..ea69e95
--- /dev/null
+++ b/app/views/gs_parameters/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for(@gs_parameter) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('gs_parameters.form.submit') \ No newline at end of file
diff --git a/app/views/gs_parameters/_form_core.html.haml b/app/views/gs_parameters/_form_core.html.haml
new file mode 100644
index 0000000..70b3773
--- /dev/null
+++ b/app/views/gs_parameters/_form_core.html.haml
@@ -0,0 +1,4 @@
+.inputs
+ = f.input :value, :label => t('gs_parameters.form.value.label'), :hint => conditional_hint('gs_parameters.form.value.hint'), :autofocus => true
+ = f.input :class_type, :collection => ['String', 'Integer', 'Boolean', 'YAML', 'Nil'], :label => t('gs_parameters.form.class_type.label'), :hint => conditional_hint('gs_parameters.form.class_type.hint'), :include_blank => false
+ = f.input :description, :label => t('gs_parameters.form.description.label'), :hint => conditional_hint('gs_parameters.form.description.hint')
diff --git a/app/views/gs_parameters/_index_core.html.haml b/app/views/gs_parameters/_index_core.html.haml
new file mode 100644
index 0000000..3d5f3cf
--- /dev/null
+++ b/app/views/gs_parameters/_index_core.html.haml
@@ -0,0 +1,16 @@
+- cache(['gs_parameters_table_section', gs_parameters.first.section, gs_parameters.reorder(:updated_at).last, gs_parameters.pluck(:id)]) do
+ %tr
+ %th= t('gs_parameters.index.name')
+ - if !@sections
+ %th= t('gs_parameters.index.section')
+ %th= t('gs_parameters.index.value')
+
+
+ - for gs_parameter in gs_parameters
+ - cache(['gs_parameters_table_single_row', gs_parameter]) do
+ %tr
+ %td= gs_parameter.name
+ - if !@sections
+ %td= gs_parameter.section
+ %td= truncate(gs_parameter.value, :length => 50)
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => gs_parameter} \ No newline at end of file
diff --git a/app/views/gs_parameters/edit.html.haml b/app/views/gs_parameters/edit.html.haml
new file mode 100644
index 0000000..b456f43
--- /dev/null
+++ b/app/views/gs_parameters/edit.html.haml
@@ -0,0 +1,15 @@
+- content_for :title, t("gs_parameters.edit.page_title")
+
+%p
+ %strong= t('gs_parameters.show.name') + ":"
+ = @gs_parameter.name
+- if !@gs_parameter.entity.blank?
+ %p
+ %strong= t('gs_parameters.show.entity') + ":"
+ = @gs_parameter.entity
+- if !@gs_parameter.section.blank?
+ %p
+ %strong= t('gs_parameters.show.section') + ":"
+ = @gs_parameter.section
+
+= render "form" \ No newline at end of file
diff --git a/app/views/gs_parameters/index.html.haml b/app/views/gs_parameters/index.html.haml
new file mode 100644
index 0000000..9132cdd
--- /dev/null
+++ b/app/views/gs_parameters/index.html.haml
@@ -0,0 +1,15 @@
+- content_for :title, t("gs_parameters.index.page_title")
+
+- if @gs_parameters && @gs_parameters.count > 0
+ - cache(['gs_parameters_table', I18n.locale, @gs_parameters_unordered.reorder(:updated_at).last, @gs_parameters_unordered.count]) do
+ - if @sections
+ %table{:class => 'table table-striped'}
+ - @sections.each do |section|
+ %tr
+ %td{:colspan => 3}
+ %h3= section
+ -# Template Dependency: gs_parameters/_index_core
+ = render "index_core", :gs_parameters => @gs_parameters.where(:section => section)
+ - else
+ %table{:class => 'table table-striped'}
+ = render "index_core", :gs_parameters => @gs_parameters
diff --git a/app/views/gs_parameters/show.html.haml b/app/views/gs_parameters/show.html.haml
new file mode 100644
index 0000000..795d09c
--- /dev/null
+++ b/app/views/gs_parameters/show.html.haml
@@ -0,0 +1,20 @@
+- cache(@gs_parameter) do
+ - content_for :title, t("gs_parameters.show.page_title")
+
+ %p
+ %strong= t('gs_parameters.show.name') + ":"
+ = @gs_parameter.name
+ %p
+ %strong= t('gs_parameters.show.section') + ":"
+ = @gs_parameter.section
+ %p
+ %strong= t('gs_parameters.show.value') + ":"
+ = @gs_parameter.value
+ %p
+ %strong= t('gs_parameters.show.class_type') + ":"
+ = @gs_parameter.class_type
+ %p
+ %strong= t('gs_parameters.show.description') + ":"
+ = @gs_parameter.description
+
+ = render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @gs_parameter } \ No newline at end of file
diff --git a/app/views/gui_functions/_index_core.html.haml b/app/views/gui_functions/_index_core.html.haml
index 093a0d7..0d9454e 100644
--- a/app/views/gui_functions/_index_core.html.haml
+++ b/app/views/gui_functions/_index_core.html.haml
@@ -1,26 +1,27 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('gui_functions.index.category')
%th= t('gui_functions.index.name')
- @user_groups.each do |user_group|
%th= user_group
- - reset_cycle
+
- for gui_function in gui_functions
- %tr{:class => cycle('odd', 'even')}
- %td= gui_function.category
- %td
- = gui_function.name
- - if !gui_function.description.blank?
- %br
- %i= gui_function.description
- - @user_groups.each do |user_group|
- - if gui_function.gui_function_memberships.find_by_user_group_id(user_group.id)
- - if gui_function.gui_function_memberships.find_by_user_group_id(user_group.id).activated == true
- %td= 'x'
+ %tr
+ - cache(['gui_functions_table_row', I18n.locale, gui_function]) do
+ %td= gui_function.category
+ %td
+ = gui_function.name
+ - if !gui_function.description.blank?
+ %br
+ %i= gui_function.description
+ - @user_groups.each do |user_group|
+ - if gui_function.gui_function_memberships.find_by_user_group_id(user_group.id)
+ - if gui_function.gui_function_memberships.find_by_user_group_id(user_group.id).activated == true
+ %td= 'x'
+ - else
+ %td= ''
- else
- %td= ''
- - else
- %td= 'x'
+ %td= 'x'
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => gui_function} \ No newline at end of file
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => gui_function} \ No newline at end of file
diff --git a/app/views/gui_functions/edit.html.haml b/app/views/gui_functions/edit.html.haml
index f43b5bc..a041138 100644
--- a/app/views/gui_functions/edit.html.haml
+++ b/app/views/gui_functions/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("gui_functions.edit.page_title")
+- content_for :title, t("gui_functions.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gui_functions/index.html.haml b/app/views/gui_functions/index.html.haml
index ef909f0..b0a7d18 100644
--- a/app/views/gui_functions/index.html.haml
+++ b/app/views/gui_functions/index.html.haml
@@ -1,6 +1,7 @@
-- title t("gui_functions.index.page_title")
+- content_for :title, t("gui_functions.index.page_title")
- if @gui_functions && @gui_functions.count > 0
- = render "index_core", :gui_functions => @gui_functions
+ - cache(['gui_functions_table', I18n.locale, @gui_functions.reorder(:updated_at).last, @gui_functions.count]) do
+ = render "index_core", :gui_functions => @gui_functions
= render :partial => 'shared/create_link', :locals => {:child_class => GuiFunction} \ No newline at end of file
diff --git a/app/views/gui_functions/new.html.haml b/app/views/gui_functions/new.html.haml
index 6c57e9c..0e3a809 100644
--- a/app/views/gui_functions/new.html.haml
+++ b/app/views/gui_functions/new.html.haml
@@ -1,3 +1,3 @@
-- title t("gui_functions.new.page_title")
+- content_for :title, t("gui_functions.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/gui_functions/show.html.haml b/app/views/gui_functions/show.html.haml
index 0fc2dd9..91b9d2e 100644
--- a/app/views/gui_functions/show.html.haml
+++ b/app/views/gui_functions/show.html.haml
@@ -1,18 +1,19 @@
-- title t("gui_functions.show.page_title")
+- content_for :title, t("gui_functions.show.page_title")
-%p
- %strong= t('gui_functions.show.name') + ":"
- = @gui_function.name
-%p
- %strong= t('gui_functions.show.description') + ":"
- = @gui_function.description
-
-- @user_groups.each do |user_group|
+- cache(['gui_function_show', I18n.locale, @gui_function]) do
+ %p
+ %strong= t('gui_functions.show.name') + ":"
+ = @gui_function.name
%p
- %strong= "#{user_group}:"
- - if @gui_function.gui_function_memberships.where(:user_group_id => user_group.id, :activated => true).count > 0
- = 'x'
- - else
- = 'not activated'
+ %strong= t('gui_functions.show.description') + ":"
+ = @gui_function.description
+
+ - @user_groups.each do |user_group|
+ %p
+ %strong= "#{user_group}:"
+ - if @gui_function.gui_function_memberships.where(:user_group_id => user_group.id, :activated => true).count > 0
+ = 'x'
+ - else
+ = 'not activated'
-= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @gui_function } \ No newline at end of file
+ = render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @gui_function } \ No newline at end of file
diff --git a/app/views/hunt_group_members/_index_core.html.haml b/app/views/hunt_group_members/_index_core.html.haml
index 46b64c8..c6b7e4a 100644
--- a/app/views/hunt_group_members/_index_core.html.haml
+++ b/app/views/hunt_group_members/_index_core.html.haml
@@ -1,13 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('hunt_group_members.index.name')
%th= t('hunt_group_members.index.active')
%th= t('hunt_group_members.index.can_switch_status_itself')
%th= t('hunt_group_members.index.phone_numbers')
- - reset_cycle
+
- for hunt_group_member in hunt_group_members
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= hunt_group_member.name
%td= hunt_group_member.active
%td= hunt_group_member.can_switch_status_itself
diff --git a/app/views/hunt_group_members/edit.html.haml b/app/views/hunt_group_members/edit.html.haml
index 93d7b0a..97e9084 100644
--- a/app/views/hunt_group_members/edit.html.haml
+++ b/app/views/hunt_group_members/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("hunt_group_members.edit.page_title")
+- content_for :title, t("hunt_group_members.edit.page_title")
= render "form"
diff --git a/app/views/hunt_group_members/index.html.haml b/app/views/hunt_group_members/index.html.haml
index 99dc929..4001000 100644
--- a/app/views/hunt_group_members/index.html.haml
+++ b/app/views/hunt_group_members/index.html.haml
@@ -1,4 +1,4 @@
-- title t("hunt_group_members.index.page_title")
+- content_for :title, t("hunt_group_members.index.page_title")
- if @hunt_group_members.count > 0
= render "index_core", :hunt_group_members => @hunt_group_members
diff --git a/app/views/hunt_group_members/new.html.haml b/app/views/hunt_group_members/new.html.haml
index 99f52ad..31dd185 100644
--- a/app/views/hunt_group_members/new.html.haml
+++ b/app/views/hunt_group_members/new.html.haml
@@ -1,3 +1,3 @@
-- title t("hunt_group_members.new.page_title")
+- content_for :title, t("hunt_group_members.new.page_title")
= render "form"
diff --git a/app/views/hunt_group_members/show.html.haml b/app/views/hunt_group_members/show.html.haml
index 80123b8..2056db0 100644
--- a/app/views/hunt_group_members/show.html.haml
+++ b/app/views/hunt_group_members/show.html.haml
@@ -1,4 +1,4 @@
-- title t("hunt_group_members.show.page_title")
+- content_for :title, t("hunt_group_members.show.page_title")
%p
%strong= t('hunt_group_members.show.name') + ":"
diff --git a/app/views/hunt_groups/_form_core.html.haml b/app/views/hunt_groups/_form_core.html.haml
index 10a0111..53d44d1 100644
--- a/app/views/hunt_groups/_form_core.html.haml
+++ b/app/views/hunt_groups/_form_core.html.haml
@@ -1,4 +1,4 @@
.inputs
= f.input :name, :label => t('hunt_groups.form.name.label'), :hint => conditional_hint('hunt_groups.form.name.hint')
- = f.input :strategy, :as => :select, :label => t('hunt_groups.form.strategy.label'), :hint => conditional_hint('hunt_groups.form.strategy.hint'), :include_blank => false, :collection => HUNT_GROUP_STRATEGIES.map {|x| [I18n.t('hunt_groups.strategies.' + x), x] }
- = f.input :seconds_between_jumps, :collection => VALID_SECONDS_BETWEEN_JUMPS_VALUES, :label => t('hunt_groups.form.seconds_between_jumps.label'), :hint => conditional_hint('hunt_groups.form.seconds_between_jumps.hint') \ No newline at end of file
+ = f.input :strategy, :as => :select, :label => t('hunt_groups.form.strategy.label'), :hint => conditional_hint('hunt_groups.form.strategy.hint'), :include_blank => false, :collection => GsParameter.get('HUNT_GROUP_STRATEGIES').map {|x| [I18n.t('hunt_groups.strategies.' + x), x] }
+ = f.input :seconds_between_jumps, :collection => GsParameter.get('VALID_SECONDS_BETWEEN_JUMPS_VALUES'), :label => t('hunt_groups.form.seconds_between_jumps.label'), :hint => conditional_hint('hunt_groups.form.seconds_between_jumps.hint') \ No newline at end of file
diff --git a/app/views/hunt_groups/_index_core.html.haml b/app/views/hunt_groups/_index_core.html.haml
index 3000e97..16b1b5d 100644
--- a/app/views/hunt_groups/_index_core.html.haml
+++ b/app/views/hunt_groups/_index_core.html.haml
@@ -1,6 +1,6 @@
- show_seconds = hunt_groups.map{|x| ! x.seconds_between_jumps.nil? }.include?(true)
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('hunt_groups.index.name')
%th= t('hunt_groups.index.strategy')
@@ -9,9 +9,9 @@
%th= t('hunt_groups.index.phone_numbers')
%th= t('hunt_groups.index.hunt_group_members')
- - reset_cycle
+
- for hunt_group in hunt_groups
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= hunt_group.name
%td= t("hunt_groups.strategies.#{hunt_group.strategy}")
- if show_seconds
diff --git a/app/views/hunt_groups/edit.html.haml b/app/views/hunt_groups/edit.html.haml
index f2ef998..5d5b146 100644
--- a/app/views/hunt_groups/edit.html.haml
+++ b/app/views/hunt_groups/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("hunt_groups.edit.page_title")
+- content_for :title, t("hunt_groups.edit.page_title")
= render "form"
diff --git a/app/views/hunt_groups/index.html.haml b/app/views/hunt_groups/index.html.haml
index 62bc2aa..8c6fdf6 100644
--- a/app/views/hunt_groups/index.html.haml
+++ b/app/views/hunt_groups/index.html.haml
@@ -1,4 +1,4 @@
-- title t("hunt_groups.index.page_title")
+- content_for :title, t("hunt_groups.index.page_title")
- if @hunt_groups.count > 0
= render "index_core", :hunt_groups => @hunt_groups
diff --git a/app/views/hunt_groups/new.html.haml b/app/views/hunt_groups/new.html.haml
index a40e579..2c1350e 100644
--- a/app/views/hunt_groups/new.html.haml
+++ b/app/views/hunt_groups/new.html.haml
@@ -1,3 +1,3 @@
-- title t("hunt_groups.new.page_title")
+- content_for :title, t("hunt_groups.new.page_title")
= render "form"
diff --git a/app/views/hunt_groups/show.html.haml b/app/views/hunt_groups/show.html.haml
index 009af50..3ffe4f3 100644
--- a/app/views/hunt_groups/show.html.haml
+++ b/app/views/hunt_groups/show.html.haml
@@ -1,4 +1,4 @@
-- title t("hunt_groups.show.page_title")
+- content_for :title, t("hunt_groups.show.page_title")
%p
%strong= t('hunt_groups.show.name') + ":"
diff --git a/app/views/layouts/_footer.html.haml b/app/views/layouts/_footer.html.haml
new file mode 100644
index 0000000..61ea546
--- /dev/null
+++ b/app/views/layouts/_footer.html.haml
@@ -0,0 +1,17 @@
+- cache(['application_footer', I18n.locale]) do
+ %footer
+ %ul{:class => 'nav nav-pills'}
+ - if !GsParameter.get('GEMEINSCHAFT_BUILDNAME').nil?
+ %li
+ %a{:href => "http://amooma.de/gemeinschaft/gs5", :ref => 'tooltip', :title => "Gemeinschaft Version " + GsParameter.get('GEMEINSCHAFT_VERSION') + "\nBuild #" + GsParameter.get('GEMEINSCHAFT_BUILDNAME')} Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}
+ - else
+ %li
+ %a{:href => "http://amooma.de/gemeinschaft/gs5"} Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}
+ - if GuiFunction.display?('amooma_commercial_support_link_in_footer', current_user)
+ %li
+ %a{:href => "http://amooma.de"} Support und Consulting
+ - if GuiFunction.display?('gemeinschaft_mailinglist_link_in_footer', current_user)
+ %li
+ %a{:href => "https://groups.google.com/group/gs5-users/"} Mailingliste
+ %li{:class => 'pull-right'}
+ = link_to 'brought to you by AMOOMA GmbH', 'http://amooma.de' \ No newline at end of file
diff --git a/app/views/layouts/_navbar.html.haml b/app/views/layouts/_navbar.html.haml
new file mode 100644
index 0000000..d6f08cb
--- /dev/null
+++ b/app/views/layouts/_navbar.html.haml
@@ -0,0 +1,43 @@
+.navbar.navbar-inverse.navbar-fixed-top
+ .navbar-inner
+ .container
+ %a.brand{:href => (current_user.nil? ? '/' : tenant_path(current_user.current_tenant))}
+ Gemeinschaft 5
+
+ %a.btn.btn-navbar{"data-target" => ".nav-collapse", "data-toggle" => "collapse"}
+ %span.icon-bar
+ %span.icon-bar
+ %span.icon-bar
+
+ - if current_user
+ .nav-collapse.collapse
+ %ul.nav
+ %li
+ %a{:href => "#about"} About
+ %li.pull_right
+ %a{:href => "#contact"} Contact
+
+ - if current_user
+ %ul.nav.pull-right
+ %li
+ - if current_user.image?
+ =image_tag(current_user.image_url(:mini).to_s, :class => 'img-rounded')
+ - else
+ - if current_user.male?
+ = image_tag 'icons/user-male-16x.png', :class => 'img-rounded'
+ - else
+ = image_tag 'icons/user-female-16x.png', :class => 'img-rounded'
+
+ - if current_page?(tenant_user_path(current_user.current_tenant, current_user))
+ %li.active
+ %a.navbar-link{:href => tenant_user_path(current_user.current_tenant, current_user)}
+ = current_user
+ - else
+ %li
+ %a.navbar-link{:href => tenant_user_path(current_user.current_tenant, current_user)}
+ = current_user
+
+ %li
+ %a.navbar-link{:href => log_out_path}
+ %i.icon-off.icon-white
+
diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml
index 2c7faec..74331af 100644
--- a/app/views/layouts/application.html.haml
+++ b/app/views/layouts/application.html.haml
@@ -1,47 +1,38 @@
-!!! 5
-<!--[if lt IE 7]> <html lang="en" class="no-js ie6"> <![endif]-->
-<!--[if IE 7]> <html lang="en" class="no-js ie7"> <![endif]-->
-<!--[if IE 8]> <html lang="en" class="no-js ie8"> <![endif]-->
-<!--[if gt IE 8]><!-->
-%html.no-js{ :lang => "en" }
- ~#OPTIMIZE Make html lang attribute reflect the actual language.
- <!--<![endif]-->
- %header
- %meta{ :charset => "utf-8" }/
- ~#OPTIMIZE "/" seems to be supposed to make an empty element tag, but it doesn't work. HAML bug?
- %title
- = content_for?(:title) ? yield(:title) : "Untitled"
- %meta{ :name => "viewport", :content => "width=device-width, initial-scale=1.0" }/
- = stylesheet_link_tag "application"
+!!!
+%html
+ %head
+ %meta{:charset => "utf-8"}/
+ %title
+ = content_for?(:title) ? yield(:title) : "Gemeinschaft 5"
+ %meta{:name => 'viewport', :content => "width=device-width, initial-scale=1.0"}
+ - if content_for?(:meta_description)
+ %meta{:description => yield(:meta_description)}/
+ %meta{:author => "AMOOMA GmbH"}/
+ = stylesheet_link_tag "application", :media => "all"
= javascript_include_tag "application"
- = csrf_meta_tag
- = yield(:head)
-
+ = csrf_meta_tags
+ / HTML5 shim, for IE6-8 support of HTML5 elements
+ /[if lt IE 9]
+ <script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
%body
- #container
- = render :partial => "shared/header"
- = render :partial => "shared/flash", :locals => { :flash => flash}
+ .container
+ .row
+ .span12
+ - unless response.cache_control[:public]
+ - flash.each do |name, msg|
+ %div{:class => "alert alert-#{name == :notice ? "success" : "error"} fade in"}
+ %a.close{"data-dismiss" => "alert"} ×
+ = msg
- #content{:role => 'main'}
- .light
- %header.main
- .breadcrumbs= render_breadcrumbs :separator => ' » '
- - if show_title?
- %h1= yield(:title)
- = yield
+ - if current_user
+ = render_breadcrumbs :builder => ::BootstrapBreadcrumbsBuilder, :separator => "/"
- %footer#main
- %ul
- %li
- %a{:href => "http://amooma.de/gemeinschaft/gs5"} Gemeinschaft #{GEMEINSCHAFT_VERSION}
- - if GuiFunction.display?('amooma_commercial_support_link_in_footer', current_user)
- %li
- %a{:href => "http://amooma.de"} Kommerzieller Support und Consulting
- - if GuiFunction.display?('gemeinschaft_mailinglist_link_in_footer', current_user)
- %li
- %a{:href => "https://groups.google.com/group/gs5-users/"} Kostenlose Mailingliste
+ = render 'layouts/navbar'
- .amooma-logo
- %span brought to you by
- %a{ :target => '_blank', :href => "http://amooma.de/" } Amooma
+ = yield
+ .row
+ .span12
+ %hr/
+ = render 'layouts/footer'
+ / /container
diff --git a/app/views/layouts/old-application.html.haml b/app/views/layouts/old-application.html.haml
new file mode 100644
index 0000000..a2afbf8
--- /dev/null
+++ b/app/views/layouts/old-application.html.haml
@@ -0,0 +1,48 @@
+!!! 5
+<!--[if lt IE 7]> <html lang="en" class="no-js ie6"> <![endif]-->
+<!--[if IE 7]> <html lang="en" class="no-js ie7"> <![endif]-->
+<!--[if IE 8]> <html lang="en" class="no-js ie8"> <![endif]-->
+<!--[if gt IE 8]><!-->
+%html.no-js{ :lang => I18n.locale.to_s }
+ <!--<![endif]-->
+ %header
+ %meta{ :charset => "utf-8" }/
+ ~#OPTIMIZE "/" seems to be supposed to make an empty element tag, but it doesn't work. HAML bug?
+ %title
+ = content_for?(:title) ? yield(:title) : "Untitled"
+ %meta{ :name => "viewport", :content => "width=device-width, initial-scale=1.0" }/
+ = stylesheet_link_tag "application"
+ = javascript_include_tag "application"
+ = csrf_meta_tag
+ = yield(:head)
+
+ %body
+ #container
+ - cache(['application_header', I18n.locale, current_user]) do
+ = render :partial => "shared/header"
+ = render :partial => "shared/flash", :locals => { :flash => flash}
+
+ #content{:role => 'main'}
+ .light
+ %header.main
+ .breadcrumbs= render_breadcrumbs :separator => ' » '
+ - if show_title?
+ %h1= yield(:title)
+ = yield
+
+ - cache(['application_footer', I18n.locale]) do
+ %footer#main
+ %ul
+ %li
+ %a{:href => "http://amooma.de/gemeinschaft/gs5"} Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}
+ - if GuiFunction.display?('amooma_commercial_support_link_in_footer', current_user)
+ %li
+ %a{:href => "http://amooma.de"} Kommerzieller Support und Consulting
+ - if GuiFunction.display?('gemeinschaft_mailinglist_link_in_footer', current_user)
+ %li
+ %a{:href => "https://groups.google.com/group/gs5-users/"} Kostenlose Mailingliste
+
+ .amooma-logo
+ %span brought to you by
+ %a{ :target => '_blank', :href => "http://amooma.de/" } Amooma
+
diff --git a/app/views/layouts/old_navbar.html.haml b/app/views/layouts/old_navbar.html.haml
new file mode 100644
index 0000000..4d795e4
--- /dev/null
+++ b/app/views/layouts/old_navbar.html.haml
@@ -0,0 +1,10 @@
+.navbar.navbar-inverse.navbar-fixed-top
+ .navbar-inner
+ .container
+ %a.btn.btn-navbar{"data-target" => ".nav-collapse", "data-toggle" => "collapse"}
+ %span.icon-bar
+ %span.icon-bar
+ %span.icon-bar
+ %a.brand{:href => "/"} Gemeinschaft 5
+
+ / /.nav-collapse
diff --git a/log/.gitkeep b/app/views/layouts/test.haml
index e69de29..e69de29 100644
--- a/log/.gitkeep
+++ b/app/views/layouts/test.haml
diff --git a/app/views/manufacturers/_index_core.html.haml b/app/views/manufacturers/_index_core.html.haml
index 8937909..5efa5d9 100644
--- a/app/views/manufacturers/_index_core.html.haml
+++ b/app/views/manufacturers/_index_core.html.haml
@@ -1,13 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('manufacturers.index.name')
%th= t('manufacturers.index.ieee_name')
%th= t('manufacturers.index.homepage_url')
%th= t('manufacturers.index.phone_models')
- - reset_cycle
+
- for manufacturer in manufacturers
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= manufacturer.name
%td= manufacturer.ieee_name
%td
diff --git a/app/views/manufacturers/edit.html.haml b/app/views/manufacturers/edit.html.haml
index 61bcba0..913287a 100644
--- a/app/views/manufacturers/edit.html.haml
+++ b/app/views/manufacturers/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("manufacturers.edit.page_title")
+- content_for :title, t("manufacturers.edit.page_title")
= render "form"
diff --git a/app/views/manufacturers/index.html.haml b/app/views/manufacturers/index.html.haml
index 43fecc6..ccdd44b 100644
--- a/app/views/manufacturers/index.html.haml
+++ b/app/views/manufacturers/index.html.haml
@@ -1,4 +1,4 @@
-- title t("manufacturers.index.page_title")
+- content_for :title, t("manufacturers.index.page_title")
= render "index_core", :manufacturers => @manufacturers
diff --git a/app/views/manufacturers/new.html.haml b/app/views/manufacturers/new.html.haml
index 4fb9dbf..9931242 100644
--- a/app/views/manufacturers/new.html.haml
+++ b/app/views/manufacturers/new.html.haml
@@ -1,3 +1,3 @@
-- title t("manufacturers.new.page_title")
+- content_for :title, t("manufacturers.new.page_title")
= render "form"
diff --git a/app/views/manufacturers/show.html.haml b/app/views/manufacturers/show.html.haml
index 1b8383b..8888402 100644
--- a/app/views/manufacturers/show.html.haml
+++ b/app/views/manufacturers/show.html.haml
@@ -1,4 +1,4 @@
-- title t("manufacturers.show.page_title")
+- content_for :title, t("manufacturers.show.page_title")
%p
%strong= t('manufacturers.show.name') + ":"
diff --git a/app/views/page/beginners_intro.de.html.haml b/app/views/page/beginners_intro.de.html.haml
index 8d129db..5eef135 100644
--- a/app/views/page/beginners_intro.de.html.haml
+++ b/app/views/page/beginners_intro.de.html.haml
@@ -1,4 +1,4 @@
-- title "Erste Schritte mit Gemeinschaft #{GEMEINSCHAFT_VERSION}!"
+- content_for :title, "Erste Schritte mit Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}!"
%p
Sie müssen als erstes mindestens zwei neue SIP-Accounts anlegen. Dabei haben Sie die Wahl zwischen folgenden Varianten:
@@ -29,5 +29,5 @@
%p
Komfortabler ist der Betrieb von im Provisioning unterstützen Telefone. Diese können Sie beim Anlegen direkt mit einem bestimmten SIP-Account verknüpfen. Danach müssen Sie nur noch die Provisioningdaten per Hand ins Telefon eintragen oder ein paar Einstellungen in Ihrem DHCP-Server vornehmen. Hilfe dazu finden Sie im #{link_to 'Wiki', 'https://github.com/amooma/GS5/wiki'} und der #{link_to 'Mailingliste', 'https://groups.google.com/group/gs5-users/'}.
%p
- Folgende Telefone werden in der Version #{GEMEINSCHAFT_VERSION} vom automatischen Provisioning unterstützt:
+ Folgende Telefone werden in der Version #{GsParameter.get('GEMEINSCHAFT_VERSION')} vom automatischen Provisioning unterstützt:
= nicely_joined_with_commata(PhoneModel.order(:name).map{|phone_model| "#{phone_model.to_s}"}) \ No newline at end of file
diff --git a/app/views/page/beginners_intro.html.haml b/app/views/page/beginners_intro.html.haml
index 6227142..dadd99f 100644
--- a/app/views/page/beginners_intro.html.haml
+++ b/app/views/page/beginners_intro.html.haml
@@ -1,4 +1,4 @@
-- title "First steps with Gemeinschaft #{GEMEINSCHAFT_VERSION}!"
+- content_for :title, "First steps with Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}!"
%p
You have to create at least two new SIP accounts. You have the choice of two different versions:
@@ -29,5 +29,5 @@
%p
More comfortable is the use of auto provisioned phones. They can be linked to SIP accounts. After creating them in the WebGUI you have to set the Provisioning URL in the phone or setup your DHCP server to give them this data. You'll find help in our #{link_to 'Wiki', 'https://github.com/amooma/GS5/wiki'} or in our #{link_to 'mailinglist', 'https://groups.google.com/group/gs5-users/'}.
%p
- In version #{GEMEINSCHAFT_VERSION} the following phones can be used for provisioning:
+ In version #{GsParameter.get('GEMEINSCHAFT_VERSION')} the following phones can be used for provisioning:
= nicely_joined_with_commata(PhoneModel.order(:name).map{|phone_model| "#{phone_model.to_s}"}) \ No newline at end of file
diff --git a/app/views/page/conference.html.haml b/app/views/page/conference.html.haml
index 061dfd1..2fdc043 100644
--- a/app/views/page/conference.html.haml
+++ b/app/views/page/conference.html.haml
@@ -1,5 +1,5 @@
- conf_call_topic = "The next big thing"
-- title "Conference Call \u2013 Topic: #{conf_call_topic}"
+- content_for :title, "Conference Call \u2013 Topic: #{conf_call_topic}"
%section.conference
diff --git a/app/views/page/index.de.html.haml b/app/views/page/index.de.html.haml
index 2928319..a3ca83b 100644
--- a/app/views/page/index.de.html.haml
+++ b/app/views/page/index.de.html.haml
@@ -1,4 +1,4 @@
-- title "Gemeinschaft #{GEMEINSCHAFT_VERSION}"
+- content_for :title, "Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}"
%div
%h3 Aktueller Mandant
diff --git a/app/views/page/index.html.haml b/app/views/page/index.html.haml
index 9621395..178074d 100644
--- a/app/views/page/index.html.haml
+++ b/app/views/page/index.html.haml
@@ -1,4 +1,4 @@
-- title "Gemeinschaft #{GEMEINSCHAFT_VERSION}"
+- content_for :title, "Gemeinschaft #{GsParameter.get('GEMEINSCHAFT_VERSION')}"
%div
%h3 Current tenant
diff --git a/app/views/phone_book_entries/_form_core.html.haml b/app/views/phone_book_entries/_form_core.html.haml
index c05139e..5159668 100644
--- a/app/views/phone_book_entries/_form_core.html.haml
+++ b/app/views/phone_book_entries/_form_core.html.haml
@@ -1,6 +1,6 @@
.inputs
= f.input :is_male, :collection => [[true, t('phone_book_entries.form.gender.male')], [false, t('phone_book_entries.form.gender.female')]], :label_method => :last, :value_method => :first, :label => t('phone_book_entries.form.male.label'), :hint => conditional_hint('phone_book_entries.form.gender.hint'), :label => t('phone_book_entries.form.gender.label'), :as => :radio
- = f.input :first_name, :label => t('phone_book_entries.form.first_name.label'), :hint => conditional_hint('phone_book_entries.form.first_name.hint')
+ = f.input :first_name, :label => t('phone_book_entries.form.first_name.label'), :hint => conditional_hint('phone_book_entries.form.first_name.hint'), :autofocus => true
= f.input :middle_name, :label => t('phone_book_entries.form.middle_name.label'), :hint => conditional_hint('phone_book_entries.form.middle_name.hint')
= f.input :last_name, :label => t('phone_book_entries.form.last_name.label'), :hint => conditional_hint('phone_book_entries.form.last_name.hint')
= f.input :birth_name, :label => t('phone_book_entries.form.birth_name.label'), :hint => conditional_hint('phone_book_entries.form.birth_name.hint')
diff --git a/app/views/phone_book_entries/_index_core.de.html.haml b/app/views/phone_book_entries/_index_core.de.html.haml
index 0c6e74b..fe72d26 100644
--- a/app/views/phone_book_entries/_index_core.de.html.haml
+++ b/app/views/phone_book_entries/_index_core.de.html.haml
@@ -2,39 +2,41 @@
%section.phone-book-entries
%header.entries-nav= render :partial => "phone_book_entries/navigation"
.content
- - reset_cycle
- %table
- - for entry in phone_book_entries
- ~# Dear IE7,
- ~# Because of you we have to do this with a table.
- ~# With Love,
- ~# Mario.
- %tr.phone-book-entry{:class => cycle('odd', 'even'), :"itemscope itemtype" => "http://schema.org/Person"}
- %td.thumbnail
- = image_tag(entry.image_url(:small).to_s, :itemprop => 'image')
- %td.user
- - if entry.is_organization == true
- %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
- - else
- %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
- %a.company{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'memberOf'}= entry.organization
- %td.contact
- - if @found_phone_numbers and @found_phone_numbers.where(:phone_numberable_id => entry.id)
- %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= @found_phone_numbers.where(:phone_numberable_id => entry.id).first
- - elsif entry.phone_numbers.first
- %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= entry.phone_numbers.first
- - if entry.phone_numbers.count > 1
- %a.more{:href => phone_book_phone_book_entry_path(entry.phone_book, entry)}= t('phone_book_entries.index.more_numbers', :numbers => (entry.phone_numbers.count-1))
- %td.extra
- - if !entry.description.blank?
- %strong Beschreibung:
- %div
- = entry.description
- - if !entry.homepage_organization.blank?
- %br
- =link_to entry.homepage_organization, entry.homepage_organization
- - if can? :edit, entry
- %td= link_to t('phone_book_entries.index.actions.edit'), edit_phone_book_phone_book_entry_path( entry.phone_book, entry )
- - if can? :destroy, entry
- %td= link_to t('phone_book_entries.index.actions.destroy'), [entry.phone_book, entry], :confirm => t('phone_book_entries.index.actions.confirm'), :method => :delete
+ - cache(['phone_book_entries_table', I18n.locale, current_user, phone_book_entries]) do
+
+ %table{:class => 'table table-striped'}
+ - for entry in phone_book_entries
+ - cache(['phone_book_entries_table_tr', I18n.locale, current_user, entry]) do
+ ~# Dear IE7,
+ ~# Because of you we have to do this with a table.
+ ~# With Love,
+ ~# Mario.
+ %tr.phone-book-entry{:"itemscope itemtype" => "http://schema.org/Person"}
+ %td.thumbnail
+ = image_tag(entry.image_url(:small).to_s, :itemprop => 'image')
+ %td.user
+ - if entry.is_organization == true
+ %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
+ - else
+ %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
+ %a.company{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'memberOf'}= entry.organization
+ %td.contact
+ - if @found_phone_numbers and @found_phone_numbers.where(:phone_numberable_id => entry.id)
+ %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= @found_phone_numbers.where(:phone_numberable_id => entry.id).first
+ - elsif entry.phone_numbers.first
+ %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= entry.phone_numbers.first
+ - if entry.phone_numbers.count > 1
+ %a.more{:href => phone_book_phone_book_entry_path(entry.phone_book, entry)}= t('phone_book_entries.index.more_numbers', :numbers => (entry.phone_numbers.count-1))
+ %td.extra
+ - if !entry.description.blank?
+ %strong Beschreibung:
+ %div
+ = entry.description
+ - if !entry.homepage_organization.blank?
+ %br
+ =link_to entry.homepage_organization, entry.homepage_organization
+ - if can? :edit, entry
+ %td= link_to t('phone_book_entries.index.actions.edit'), edit_phone_book_phone_book_entry_path( entry.phone_book, entry )
+ - if can? :destroy, entry
+ %td= link_to t('phone_book_entries.index.actions.destroy'), [entry.phone_book, entry], :confirm => t('phone_book_entries.index.actions.confirm'), :method => :delete
%footer.entries-nav= render :partial => "phone_book_entries/navigation"
diff --git a/app/views/phone_book_entries/_index_core.html.haml b/app/views/phone_book_entries/_index_core.html.haml
index 9054833..6e35221 100644
--- a/app/views/phone_book_entries/_index_core.html.haml
+++ b/app/views/phone_book_entries/_index_core.html.haml
@@ -2,39 +2,42 @@
%section.phone-book-entries
%header.entries-nav= render :partial => "phone_book_entries/navigation"
.content
- - reset_cycle
- %table
- - for entry in phone_book_entries
- ~# Dear IE7,
- ~# Because of you we have to do this with a table.
- ~# With Love,
- ~# Mario.
- %tr.phone-book-entry{:class => cycle('odd', 'even'), :"itemscope itemtype" => "http://schema.org/Person"}
- %td.thumbnail
- = image_tag(entry.image_url(:small).to_s, :itemprop => 'image')
- %td.user
- - if entry.is_organization == true
- %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
- - else
- %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
- %a.company{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'memberOf'}= entry.organization
- %td.contact
- - if @found_phone_numbers and @found_phone_numbers.where(:phone_numberable_id => entry.id)
- %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= @found_phone_numbers.where(:phone_numberable_id => entry.id).first
- - elsif entry.phone_numbers.first
- %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= entry.phone_numbers.first
- - if entry.phone_numbers.count > 1
- %a.more{:href => phone_book_phone_book_entry_path(entry.phone_book, entry)}= t('phone_book_entries.index.more_numbers', :numbers => (entry.phone_numbers.count-1))
- %td.extra
- - if !entry.description.blank?
- %strong Description:
- %div
- = entry.description
- - if !entry.homepage_organization.blank?
- %br
- =link_to entry.homepage_organization, entry.homepage_organization
- - if can? :edit, entry
- %td= link_to t('phone_book_entries.index.actions.edit'), edit_phone_book_phone_book_entry_path( entry.phone_book, entry )
- - if can? :destroy, entry
- %td= link_to t('phone_book_entries.index.actions.destroy'), [entry.phone_book, entry], :confirm => t('phone_book_entries.index.actions.confirm'), :method => :delete
+ - cache(['phone_book_entries_table', I18n.locale, current_user, phone_book_entries]) do
+
+
+ %table{:class => 'table table-striped'}
+ - for entry in phone_book_entries
+ - cache(['phone_book_entries_table_tr', I18n.locale, current_user, entry]) do
+ ~# Dear IE7,
+ ~# Because of you we have to do this with a table.
+ ~# With Love,
+ ~# Mario.
+ %tr.phone-book-entry{:"itemscope itemtype" => "http://schema.org/Person"}
+ %td.thumbnail
+ = image_tag(entry.image_url(:small).to_s, :itemprop => 'image')
+ %td.user
+ - if entry.is_organization == true
+ %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
+ - else
+ %a.name{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => "name"}= entry
+ %a.company{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'memberOf'}= entry.organization
+ %td.contact
+ - if @found_phone_numbers and @found_phone_numbers.where(:phone_numberable_id => entry.id)
+ %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= @found_phone_numbers.where(:phone_numberable_id => entry.id).first
+ - elsif entry.phone_numbers.first
+ %a.phone{:href=> phone_book_phone_book_entry_path(entry.phone_book, entry), :itemprop => 'telephone'}= entry.phone_numbers.first
+ - if entry.phone_numbers.count > 1
+ %a.more{:href => phone_book_phone_book_entry_path(entry.phone_book, entry)}= t('phone_book_entries.index.more_numbers', :numbers => (entry.phone_numbers.count-1))
+ %td.extra
+ - if !entry.description.blank?
+ %strong Description:
+ %div
+ = entry.description
+ - if !entry.homepage_organization.blank?
+ %br
+ =link_to entry.homepage_organization, entry.homepage_organization
+ - if can? :edit, entry
+ %td= link_to t('phone_book_entries.index.actions.edit'), edit_phone_book_phone_book_entry_path( entry.phone_book, entry )
+ - if can? :destroy, entry
+ %td= link_to t('phone_book_entries.index.actions.destroy'), [entry.phone_book, entry], :confirm => t('phone_book_entries.index.actions.confirm'), :method => :delete
%footer.entries-nav= render :partial => "phone_book_entries/navigation"
diff --git a/app/views/phone_book_entries/edit.html.haml b/app/views/phone_book_entries/edit.html.haml
index d4fad4d..2967366 100644
--- a/app/views/phone_book_entries/edit.html.haml
+++ b/app/views/phone_book_entries/edit.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_book_entries.edit.page_title")
+- content_for :title, t("phone_book_entries.edit.page_title")
= render "form"
diff --git a/app/views/phone_book_entries/index.html.haml b/app/views/phone_book_entries/index.html.haml
index 6a17eb9..10d1ce2 100644
--- a/app/views/phone_book_entries/index.html.haml
+++ b/app/views/phone_book_entries/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_book_entries.index.page_title")
+- content_for :title, t("phone_book_entries.index.page_title")
- if @phone_books
%p
diff --git a/app/views/phone_book_entries/new.html.haml b/app/views/phone_book_entries/new.html.haml
index d72d1a4..2f3a8be 100644
--- a/app/views/phone_book_entries/new.html.haml
+++ b/app/views/phone_book_entries/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_book_entries.new.page_title")
+- content_for :title, t("phone_book_entries.new.page_title")
= render "form"
diff --git a/app/views/phone_book_entries/show.html.haml b/app/views/phone_book_entries/show.html.haml
index a9e1e8f..7dd9bcb 100644
--- a/app/views/phone_book_entries/show.html.haml
+++ b/app/views/phone_book_entries/show.html.haml
@@ -1,4 +1,4 @@
-- title nil
+- content_for :title, nil
%section.phone-book-entry
.content
@@ -67,27 +67,28 @@
= @phone_book_entry.description
.widget.phones
- @phone_book_entry.phone_numbers.each do |phone_number|
- - case phone_number.name
+ - case phone_number.name.to_s.downcase
- when /fax/
.fax
- %a= phone_number
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
%span= phone_number.name
- when /home/
.home
- %a= phone_number
- %span= phone_number.name
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
+ %span
- when /mobile/
.cellphone
- %a= phone_number
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
%span= phone_number.name
- when /office/
.office
- %a= phone_number
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
%span= phone_number.name
- else
.phone
- %a= phone_number
+ = link_to phone_number, call_phone_book_entry_phone_number_path(@phone_book_entry, phone_number), :method => :put, :title => t('phone_numbers.show.actions.call')
%span= phone_number.name
+
= link_to t('phone_book_entries.show.manage_phone_numbers'), phone_book_entry_phone_numbers_path(@phone_book_entry)
.widget.adresses
diff --git a/app/views/phone_book_entries/show.html.haml.examlple b/app/views/phone_book_entries/show.html.haml.examlple
index 176ad04..980f776 100644
--- a/app/views/phone_book_entries/show.html.haml.examlple
+++ b/app/views/phone_book_entries/show.html.haml.examlple
@@ -1,4 +1,4 @@
-- title nil
+- content_for :title, nil
%section.phone-book-entry
.content
diff --git a/app/views/phone_books/_index_core.html.haml b/app/views/phone_books/_index_core.html.haml
index 5f50675..accded6 100644
--- a/app/views/phone_books/_index_core.html.haml
+++ b/app/views/phone_books/_index_core.html.haml
@@ -1,16 +1,18 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('phone_books.index.name')
- %th= t('phone_books.index.description')
%th= t('phone_books.index.count')
-
- - reset_cycle
+ %th{:colspan => '3'}
+
- for phone_book in phone_books
- %tr{:class => cycle('odd', 'even')}
- %td= phone_book.name
- %td= phone_book.description
+ %tr
+ %td
+ - if phone_book.description.blank?
+ = phone_book.name
+ - else
+ %a.brand{:rel => 'tooltip', :title => phone_book.description}
+ = phone_book.name
%td
= number_with_delimiter( phone_book.phone_book_entries.count )
- = render :partial => 'shared/create_link', :locals => {:parent => phone_book, :child_class => PhoneBookEntry, :short_link => true}
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => phone_book.phone_bookable, :child => phone_book} \ No newline at end of file
diff --git a/app/views/phone_books/edit.html.haml b/app/views/phone_books/edit.html.haml
index 36c945b..e1d4553 100644
--- a/app/views/phone_books/edit.html.haml
+++ b/app/views/phone_books/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_books.edit.page_title", :resource => @phone_book)
+- content_for :title, t("phone_books.edit.page_title", :resource => @phone_book)
= render "form"
diff --git a/app/views/phone_books/index.html.haml b/app/views/phone_books/index.html.haml
index 52b4e9b..e681878 100644
--- a/app/views/phone_books/index.html.haml
+++ b/app/views/phone_books/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_books.index.page_title")
+- content_for :title, t("phone_books.index.page_title")
- if @phone_books.count > 0
= render "index_core", :phone_books => @phone_books
diff --git a/app/views/phone_books/new.html.haml b/app/views/phone_books/new.html.haml
index e96ce1e..66d6e99 100644
--- a/app/views/phone_books/new.html.haml
+++ b/app/views/phone_books/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_books.new.page_title")
+- content_for :title, t("phone_books.new.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/phone_books/show.html.haml b/app/views/phone_books/show.html.haml
index 047b15e..5140b91 100644
--- a/app/views/phone_books/show.html.haml
+++ b/app/views/phone_books/show.html.haml
@@ -1,4 +1,4 @@
-- title @phone_book
+- content_for :title, @phone_book
- if ! @phone_book.description.blank?
%p
%strong= t('phone_books.show.description') + ":"
diff --git a/app/views/phone_models/_index_core.html.haml b/app/views/phone_models/_index_core.html.haml
index b07eb68..b899a5c 100644
--- a/app/views/phone_models/_index_core.html.haml
+++ b/app/views/phone_models/_index_core.html.haml
@@ -1,13 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('phone_models.index.name')
%th= t('phone_models.index.product_manual_homepage_url')
%th= t('phone_models.index.product_homepage_url')
%th= t('phone_models.index.number_of_phones')
- - reset_cycle
+
- for phone_model in phone_models
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= phone_model.name
%td
- if phone_model.product_manual_homepage_url
diff --git a/app/views/phone_models/edit.html.haml b/app/views/phone_models/edit.html.haml
index bf31ffc..ee10d3e 100644
--- a/app/views/phone_models/edit.html.haml
+++ b/app/views/phone_models/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_models.edit.page_title")
+- content_for :title, t("phone_models.edit.page_title")
= render "form"
diff --git a/app/views/phone_models/index.html.haml b/app/views/phone_models/index.html.haml
index 90aa4ce..e37243a 100644
--- a/app/views/phone_models/index.html.haml
+++ b/app/views/phone_models/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_models.index.page_title")
+- content_for :title, t("phone_models.index.page_title")
- if @phone_models.count > 0
= render "index_core", :phone_models => @phone_models
diff --git a/app/views/phone_models/new.html.haml b/app/views/phone_models/new.html.haml
index 9e900d4..a60bc68 100644
--- a/app/views/phone_models/new.html.haml
+++ b/app/views/phone_models/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_models.new.page_title")
+- content_for :title, t("phone_models.new.page_title")
= render "form"
diff --git a/app/views/phone_models/show.html.haml b/app/views/phone_models/show.html.haml
index 06fae4b..5e16bda 100644
--- a/app/views/phone_models/show.html.haml
+++ b/app/views/phone_models/show.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_models.show.page_title")
+- content_for :title, t("phone_models.show.page_title")
%p
%strong= t('phone_models.show.name') + ":"
diff --git a/app/views/phone_number_ranges/_index_core.html.haml b/app/views/phone_number_ranges/_index_core.html.haml
index 24ea96d..b378be8 100644
--- a/app/views/phone_number_ranges/_index_core.html.haml
+++ b/app/views/phone_number_ranges/_index_core.html.haml
@@ -1,13 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('phone_number_ranges.index.name')
%th= t('phone_number_ranges.index.description')
%th= t('phone_number_ranges.index.numbers')
%th= t('phone_number_ranges.index.amount')
- - reset_cycle
+
- for phone_number_range in phone_number_ranges
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= t("phone_number_ranges.ranges.#{phone_number_range}.label")
%td= t("phone_number_ranges.ranges.#{phone_number_range}.description")
%td
diff --git a/app/views/phone_number_ranges/edit.html.haml b/app/views/phone_number_ranges/edit.html.haml
index fbf6d12..791be71 100644
--- a/app/views/phone_number_ranges/edit.html.haml
+++ b/app/views/phone_number_ranges/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_number_ranges.edit.page_title", :resource => @phone_number_range)
+- content_for :title, t("phone_number_ranges.edit.page_title", :resource => @phone_number_range)
= render "form"
diff --git a/app/views/phone_number_ranges/index.html.haml b/app/views/phone_number_ranges/index.html.haml
index 56cf137..769dc68 100644
--- a/app/views/phone_number_ranges/index.html.haml
+++ b/app/views/phone_number_ranges/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_number_ranges.index.page_title")
+- content_for :title, t("phone_number_ranges.index.page_title")
- if @phone_number_ranges.count > 0
= render "index_core", :phone_number_ranges => @phone_number_ranges
diff --git a/app/views/phone_number_ranges/new.html.haml b/app/views/phone_number_ranges/new.html.haml
index d26b34d..1e5eab0 100644
--- a/app/views/phone_number_ranges/new.html.haml
+++ b/app/views/phone_number_ranges/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_number_ranges.new.page_title")
+- content_for :title, t("phone_number_ranges.new.page_title")
= render "form"
diff --git a/app/views/phone_number_ranges/show.html.haml b/app/views/phone_number_ranges/show.html.haml
index 64df556..fdb54a7 100644
--- a/app/views/phone_number_ranges/show.html.haml
+++ b/app/views/phone_number_ranges/show.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_number_ranges.show.page_title")
+- content_for :title, t("phone_number_ranges.show.page_title")
%p
%strong= t('phone_number_ranges.show.name') + ":"
diff --git a/app/views/phone_numbers/_form_core.html.haml b/app/views/phone_numbers/_form_core.html.haml
index add3039..a1ce1f3 100644
--- a/app/views/phone_numbers/_form_core.html.haml
+++ b/app/views/phone_numbers/_form_core.html.haml
@@ -2,9 +2,9 @@
- if @phone_book_entry
= f.input :name, :collection => ['Office', 'Home', 'Mobile', 'Fax'], :include_blank => false, :label => t('phone_numbers.form.name.label'), :hint => conditional_hint('phone_numbers.form.name.hint')
- = f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint')
+ = f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :autofocus => true
- else
- if @callthrough || @hunt_group_member || @access_authorization || @current_user.current_tenant.array_of_available_internal_extensions_and_dids.count == 0 || @current_user.current_tenant.array_of_available_internal_extensions_and_dids.count > 250
- = f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint')
+ = f.input :number, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :autofocus => true
- else
- = f.input :number, :collection => @current_user.current_tenant.array_of_available_internal_extensions_and_dids, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :include_blank => false
+ = f.input :number, :collection => @current_user.current_tenant.array_of_available_internal_extensions_and_dids, :label => t('phone_numbers.form.number.label'), :hint => conditional_hint('phone_numbers.form.number.hint'), :include_blank => false, :autofocus => true
diff --git a/app/views/phone_numbers/_index_core.html.haml b/app/views/phone_numbers/_index_core.html.haml
index 06b27c8..f41c949 100644
--- a/app/views/phone_numbers/_index_core.html.haml
+++ b/app/views/phone_numbers/_index_core.html.haml
@@ -1,12 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
- if phone_numbers.count > 1 && phone_numbers.first.phone_numberable_type == 'PhoneBookEntry'
%th= t('phone_numbers.index.name')
%th= t('phone_numbers.index.number')
+ %th{:colspan => '3'}
- - reset_cycle
+
- for phone_number in phone_numbers.order(:position)
- %tr{:class => cycle('odd', 'even')}
+ %tr
- if phone_number.phone_numberable_type == 'PhoneBookEntry'
%td= phone_number.name
%td= phone_number
diff --git a/app/views/phone_numbers/edit.html.haml b/app/views/phone_numbers/edit.html.haml
index d238d3d..14683d2 100644
--- a/app/views/phone_numbers/edit.html.haml
+++ b/app/views/phone_numbers/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_numbers.edit.page_title", :resource => "" )
+- content_for :title, t("phone_numbers.edit.page_title", :resource => "" )
= render "form" \ No newline at end of file
diff --git a/app/views/phone_numbers/index.html.haml b/app/views/phone_numbers/index.html.haml
index 2161739..08a2aa3 100644
--- a/app/views/phone_numbers/index.html.haml
+++ b/app/views/phone_numbers/index.html.haml
@@ -1,4 +1,4 @@
-- title @parent
+- content_for :title, @parent
- if @phone_numbers.count > 0
= render "index_core", :phone_numbers => @phone_numbers
diff --git a/app/views/phone_numbers/new.html.haml b/app/views/phone_numbers/new.html.haml
index e91f4f4..364a4bd 100644
--- a/app/views/phone_numbers/new.html.haml
+++ b/app/views/phone_numbers/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_numbers.new.page_title")
+- content_for :title, t("phone_numbers.new.page_title")
= render "form"
diff --git a/app/views/phone_numbers/show.html.haml b/app/views/phone_numbers/show.html.haml
index 30c48bc..de6cb1b 100644
--- a/app/views/phone_numbers/show.html.haml
+++ b/app/views/phone_numbers/show.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_numbers.show.page_title")
+- content_for :title, t("phone_numbers.show.page_title")
- if @phone_number.phone_numberable.class == PhoneBookEntry
%p
diff --git a/app/views/phone_sip_accounts/_index_core.html.haml b/app/views/phone_sip_accounts/_index_core.html.haml
index 89afb2b..1e6d3ca 100644
--- a/app/views/phone_sip_accounts/_index_core.html.haml
+++ b/app/views/phone_sip_accounts/_index_core.html.haml
@@ -1,12 +1,12 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('phone_sip_accounts.index.phone_id')
%th= t('phone_sip_accounts.index.sip_account_id')
%th= t('phone_sip_accounts.index.position')
-
- - reset_cycle
+ %th{:colspan => '3'}
+
- for phone_sip_account in phone_sip_accounts
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= phone_sip_account.phone
%td= phone_sip_account.sip_account
%td= phone_sip_account.position
diff --git a/app/views/phone_sip_accounts/index.html.haml b/app/views/phone_sip_accounts/index.html.haml
index a9e3f85..f9ff716 100644
--- a/app/views/phone_sip_accounts/index.html.haml
+++ b/app/views/phone_sip_accounts/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_sip_accounts.index.page_title")
+- content_for :title, t("phone_sip_accounts.index.page_title")
- if @phone_sip_accounts.count > 0
=render "index_core", :phone_sip_accounts => @phone_sip_accounts
diff --git a/app/views/phone_sip_accounts/new.html.haml b/app/views/phone_sip_accounts/new.html.haml
index bfe40b8..3ad8895 100644
--- a/app/views/phone_sip_accounts/new.html.haml
+++ b/app/views/phone_sip_accounts/new.html.haml
@@ -1,3 +1,3 @@
-- title t("phone_sip_accounts.new.page_title")
+- content_for :title, t("phone_sip_accounts.new.page_title")
= render "form"
diff --git a/app/views/phone_sip_accounts/show.html.haml b/app/views/phone_sip_accounts/show.html.haml
index 0dd5a9b..54e1e5d 100644
--- a/app/views/phone_sip_accounts/show.html.haml
+++ b/app/views/phone_sip_accounts/show.html.haml
@@ -1,4 +1,4 @@
-- title t("phone_sip_accounts.show.page_title")
+- content_for :title, t("phone_sip_accounts.show.page_title")
%p
%strong= t('phone_sip_accounts.show.phone_id') + ":"
diff --git a/app/views/phones/_form_core.html.haml b/app/views/phones/_form_core.html.haml
index e0c664b..17b9ca8 100644
--- a/app/views/phones/_form_core.html.haml
+++ b/app/views/phones/_form_core.html.haml
@@ -9,7 +9,7 @@
:javascript
$(".fallback_sip_account_dropdown").hide()
- - if defined? NIGHTLY_REBOOT_OF_PHONES && NIGHTLY_REBOOT_OF_PHONES == true
+ - if defined? GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') && GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') == true
= f.input :nightly_reboot, :label => t('phones.form.nightly_reboot.label'), :hint => conditional_hint('phones.form.nightly_reboot.hint')
- - if defined? PROVISIONING_KEY_LENGTH && PROVISIONING_KEY_LENGTH > 0
+ - if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0
= f.input :provisioning_key_active, :label => t('phones.form.provisioning_key_active.label'), :hint => conditional_hint('phones.form.provisioning_key_active.hint')
diff --git a/app/views/phones/_index_core.html.haml b/app/views/phones/_index_core.html.haml
index c442d7f..fc1ad19 100644
--- a/app/views/phones/_index_core.html.haml
+++ b/app/views/phones/_index_core.html.haml
@@ -1,13 +1,13 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('phones.index.mac_address')
%th= t('phones.index.phone_model_id')
%th= t('phones.index.hot_deskable')
%th= t('phones.index.ip_address')
- - reset_cycle
+
- for phone in phones
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= phone.pretty_mac_address
%td= phone.phone_model
%td= phone.hot_deskable
diff --git a/app/views/phones/edit.html.haml b/app/views/phones/edit.html.haml
index cdbacac..9452e2a 100644
--- a/app/views/phones/edit.html.haml
+++ b/app/views/phones/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("phones.edit.page_title", :resource => @phone.mac_address)
+- content_for :title, t("phones.edit.page_title", :resource => @phone.mac_address)
= render "form"
diff --git a/app/views/phones/index.html.haml b/app/views/phones/index.html.haml
index 785adf9..4de7919 100644
--- a/app/views/phones/index.html.haml
+++ b/app/views/phones/index.html.haml
@@ -1,4 +1,4 @@
-- title t("phones.index.page_title")
+- content_for :title, t("phones.index.page_title")
- if @phones.count > 0
= render "index_core", :phones => @phones
diff --git a/app/views/phones/new.html.haml b/app/views/phones/new.html.haml
index ae0a539..95fbdf2 100644
--- a/app/views/phones/new.html.haml
+++ b/app/views/phones/new.html.haml
@@ -1,4 +1,4 @@
-- title t("phones.new.page_title")
+- content_for :title, t("phones.new.page_title")
- if !@fallback_sip_accounts.any? && can?(:create, current_user.current_tenant.sip_accounts.build)
%p
diff --git a/app/views/phones/show.html.haml b/app/views/phones/show.html.haml
index a7ee952..faf4061 100644
--- a/app/views/phones/show.html.haml
+++ b/app/views/phones/show.html.haml
@@ -1,4 +1,4 @@
-- title t("phones.show.page_title")
+- content_for :title, t("phones.show.page_title")
%p
%strong= t('phones.show.mac_address') + ":"
@@ -16,12 +16,12 @@
%strong= t('phones.show.fallback_sip_account_id') + ":"
= @phone.fallback_sip_account
-- if defined? NIGHTLY_REBOOT_OF_PHONES && NIGHTLY_REBOOT_OF_PHONES == true
+- if defined? GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') && GsParameter.get('NIGHTLY_REBOOT_OF_PHONES') == true
%p
%strong= t('phones.show.nightly_reboot') + ":"
= @phone.nightly_reboot
-- if defined? PROVISIONING_KEY_LENGTH && PROVISIONING_KEY_LENGTH > 0
+- if !GsParameter.get('PROVISIONING_KEY_LENGTH').nil? && GsParameter.get('PROVISIONING_KEY_LENGTH') > 0
%p
%strong= t('phones.show.provisioning_key_active') + ":"
= @phone.provisioning_key_active
@@ -31,9 +31,17 @@
- if @phone.ip_address.blank? && @phone.phone_model.manufacturer.ieee_name == 'SNOM Technology AG'
%p
- Sollten Sie Ihren DHCP-Server noch nicht für das automatische Konfigurieren der GS5 Provisionierungs-URL konfiguriert haben, können Sie manuell in Ihrem Telefon die folgende Provisionierungs-URL eingeben. Das "{mac}" bitte genau so eingeben, es wird vom Telefon automatisch mit der eigenen MAC-Adresse befüllt:
+ Sollten Sie Ihren DHCP-Server noch nicht für das automatische Konfigurieren der GS5 Provisionierungs-URL konfiguriert haben, können Sie manuell in Ihrem Telefon die folgende Provisionierungs-URL eingeben.
+ %p
+ Das entsprechende Eingabefeld finden Sie unter
+ %br
+ Advanced -> Update -> Setting URL
+ %p
+ Das "{mac}" bitte genau so eingeben, es wird vom Telefon automatisch mit der eigenen MAC-Adresse befüllt:
%pre
= "http://#{GemeinschaftSetup.first.sip_domain.host}/settings-{mac}"
+ %p
+ Danach müssen Sie die Konfiguration abspeichern und das Telefon booten.
= render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @phone.phoneable, :child => @phone }
diff --git a/app/views/ringtones/_index_core.html.haml b/app/views/ringtones/_index_core.html.haml
index c39357a..e3b9a32 100644
--- a/app/views/ringtones/_index_core.html.haml
+++ b/app/views/ringtones/_index_core.html.haml
@@ -1,11 +1,11 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('ringtones.index.audio')
%th= t('ringtones.index.bellcore_id')
- - reset_cycle
+
- for ringtone in ringtones
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= ringtone.audio
%td= ringtone.bellcore_id
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => ringtone.ringtoneable, :child => ringtone} \ No newline at end of file
diff --git a/app/views/ringtones/edit.html.haml b/app/views/ringtones/edit.html.haml
index 6779190..341b97f 100644
--- a/app/views/ringtones/edit.html.haml
+++ b/app/views/ringtones/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("ringtones.edit.page_title")
+- content_for :title, t("ringtones.edit.page_title")
= render "form"
diff --git a/app/views/ringtones/index.html.haml b/app/views/ringtones/index.html.haml
index 4da75fa..2eea5fe 100644
--- a/app/views/ringtones/index.html.haml
+++ b/app/views/ringtones/index.html.haml
@@ -1,4 +1,4 @@
-- title t("ringtones.index.page_title")
+- content_for :title, t("ringtones.index.page_title")
- if @ringtones.count > 0
= render "index_core", :ringtones => @ringtones
diff --git a/app/views/ringtones/new.html.haml b/app/views/ringtones/new.html.haml
index 025f440..de0070c 100644
--- a/app/views/ringtones/new.html.haml
+++ b/app/views/ringtones/new.html.haml
@@ -1,3 +1,3 @@
-- title t("ringtones.new.page_title")
+- content_for :title, t("ringtones.new.page_title")
= render "form"
diff --git a/app/views/ringtones/show.html.haml b/app/views/ringtones/show.html.haml
index 408b808..7e0a011 100644
--- a/app/views/ringtones/show.html.haml
+++ b/app/views/ringtones/show.html.haml
@@ -1,4 +1,4 @@
-- title t("ringtones.show.page_title")
+- content_for :title, t("ringtones.show.page_title")
- if 1 == 2
%p
diff --git a/app/views/route_elements/_form.html.haml b/app/views/route_elements/_form.html.haml
new file mode 100644
index 0000000..8feacaa
--- /dev/null
+++ b/app/views/route_elements/_form.html.haml
@@ -0,0 +1,7 @@
+= simple_form_for([@call_route, @route_element]) do |f|
+ = f.error_notification
+
+ = render "form_core", :f => f
+
+ .actions
+ = f.button :submit, conditional_t('route_elements.form.submit') \ No newline at end of file
diff --git a/app/views/route_elements/_form_core.html.haml b/app/views/route_elements/_form_core.html.haml
new file mode 100644
index 0000000..a9a38a7
--- /dev/null
+++ b/app/views/route_elements/_form_core.html.haml
@@ -0,0 +1,7 @@
+.inputs
+ = f.input :var_in, :label => t('route_elements.form.var_in.label'), :hint => conditional_hint('route_elements.form.var_in.hint')
+ = f.input :var_out, :label => t('route_elements.form.var_out.label'), :hint => conditional_hint('route_elements.form.var_out.hint')
+ = f.input :pattern, :label => t('route_elements.form.pattern.label'), :hint => conditional_hint('route_elements.form.pattern.hint')
+ = f.input :replacement, :label => t('route_elements.form.replacement.label'), :hint => conditional_hint('route_elements.form.replacement.hint')
+ = f.input :action, :collection => RouteElement::ELEMENT_ACTIONS, :label => t('route_elements.form.action.label'), :hint => conditional_hint('route_elements.form.action.hint'), :include_blank => false
+ = f.input :mandatory, :label => t('route_elements.form.mandatory.label'), :hint => conditional_hint('route_elements.form.mandatory.hint')
diff --git a/app/views/route_elements/_index_core.html.haml b/app/views/route_elements/_index_core.html.haml
new file mode 100644
index 0000000..5336057
--- /dev/null
+++ b/app/views/route_elements/_index_core.html.haml
@@ -0,0 +1,19 @@
+%table{:class => 'table table-striped'}
+ %tr
+ %th= t('route_elements.index.var_in')
+ %th= t('route_elements.index.var_out')
+ %th= t('route_elements.index.pattern')
+ %th= t('route_elements.index.replacement')
+ %th= t('route_elements.index.action')
+ %th= t('route_elements.index.mandatory')
+
+
+ - for route_element in route_elements
+ %tr
+ %td= route_element.var_in
+ %td= route_element.var_out
+ %td= route_element.pattern
+ %td= route_element.replacement
+ %td= route_element.action
+ %td= route_element.mandatory
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @call_route, :child => route_element} \ No newline at end of file
diff --git a/app/views/route_elements/edit.html.haml b/app/views/route_elements/edit.html.haml
new file mode 100644
index 0000000..c2da3e6
--- /dev/null
+++ b/app/views/route_elements/edit.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("route_elements.edit.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/route_elements/index.html.haml b/app/views/route_elements/index.html.haml
new file mode 100644
index 0000000..43d47f1
--- /dev/null
+++ b/app/views/route_elements/index.html.haml
@@ -0,0 +1,6 @@
+- content_for :title, t("route_elements.index.page_title")
+
+- if @route_elements && @route_elements.count > 0
+ = render "index_core", :route_elements => @route_elements
+
+= render :partial => 'shared/create_link', :locals => {:parent => @call_route, :child_class => RouteElement} \ No newline at end of file
diff --git a/app/views/route_elements/new.html.haml b/app/views/route_elements/new.html.haml
new file mode 100644
index 0000000..2b9b9c1
--- /dev/null
+++ b/app/views/route_elements/new.html.haml
@@ -0,0 +1,3 @@
+- content_for :title, t("route_elements.new.page_title")
+
+= render "form" \ No newline at end of file
diff --git a/app/views/route_elements/show.html.haml b/app/views/route_elements/show.html.haml
new file mode 100644
index 0000000..808f2a0
--- /dev/null
+++ b/app/views/route_elements/show.html.haml
@@ -0,0 +1,22 @@
+- content_for :title, t("route_elements.show.page_title")
+
+%p
+ %strong= t('route_elements.show.var_in') + ":"
+ = @route_element.var_in
+%p
+ %strong= t('route_elements.show.var_out') + ":"
+ = @route_element.var_out
+%p
+ %strong= t('route_elements.show.pattern') + ":"
+ = @route_element.pattern
+%p
+ %strong= t('route_elements.show.replacement') + ":"
+ = @route_element.replacement
+%p
+ %strong= t('route_elements.show.action') + ":"
+ = @route_element.action
+%p
+ %strong= t('route_elements.show.mandatory') + ":"
+ = @route_element.mandatory
+
+= render :partial => 'shared/show_edit_destroy_part', :locals => {:parent => @call_route, :child => @route_element } \ No newline at end of file
diff --git a/app/views/sessions/new.html.haml b/app/views/sessions/new.html.haml
index 8ad77b1..f386a5d 100644
--- a/app/views/sessions/new.html.haml
+++ b/app/views/sessions/new.html.haml
@@ -1,4 +1,4 @@
-- title t("sessions.new.page_title")
+- content_for :title, t("sessions.new.page_title")
= simple_form_for :sessions, :url => sessions_path do |t|
= t.input :login_data, :label => t('sessions.form.email'), :autofocus => true
diff --git a/app/views/shared/_create_link.html.haml b/app/views/shared/_create_link.html.haml
index 103c82b..0711ddf 100644
--- a/app/views/shared/_create_link.html.haml
+++ b/app/views/shared/_create_link.html.haml
@@ -2,10 +2,18 @@
- if can? :create, parent.send(child_class.name.underscore.pluralize).build
%p
- if t("#{child_class.name.underscore.pluralize}.index.actions.create_for").include?('translation missing') || (!(defined? short_link).nil? && short_link == true)
- = link_to t("#{child_class.name.underscore.pluralize}.index.actions.create"), method( :"new_#{parent.class.name.underscore}_#{child_class.name.underscore}_path" ).(parent)
+ %a.btn.btn-mini.btn-primary{:href => method( :"new_#{parent.class.name.underscore}_#{child_class.name.underscore}_path" ).(parent) }
+ %i.icon-plus.icon-white
+ =t("#{child_class.name.underscore.pluralize}.index.actions.create")
- else
- = link_to t("#{child_class.name.underscore.pluralize}.index.actions.create_for", :resource => parent.to_s), method( :"new_#{parent.class.name.underscore}_#{child_class.name.underscore}_path" ).(parent)
+ %a.btn.btn-mini.btn-primary{:href => method( :"new_#{parent.class.name.underscore}_#{child_class.name.underscore}_path" ).(parent) }
+ %i.icon-plus.icon-white
+ / =t("#{child_class.name.underscore.pluralize}.index.actions.create_for", :resource => parent.to_s)
+ =t("#{child_class.name.underscore.pluralize}.index.actions.create")
+
- elsif !(defined? child_class).nil?
- if can? :create, child_class
%p
- = link_to t("#{child_class.name.underscore.pluralize}.index.actions.create"), method( :"new_#{child_class.name.underscore}_path" ).() \ No newline at end of file
+ %a.btn.btn-mini.btn-primary{:href => method( :"new_#{child_class.name.underscore}_path" ).() }
+ %i.icon-plus.icon-white
+ =t("#{child_class.name.underscore.pluralize}.index.actions.create") \ No newline at end of file
diff --git a/app/views/shared/_flash.html.haml b/app/views/shared/_flash.html.haml
deleted file mode 100644
index 320fd15..0000000
--- a/app/views/shared/_flash.html.haml
+++ /dev/null
@@ -1,19 +0,0 @@
-- flash.each do |type, msg|
- .flash{:class => type}
- .light
- .sign= resolve_flash_sign(type)
- .message= msg
-
-
--# These are the available types:
--#
--# .flash.notice
--# .light
--# .sign i
--# .message Lorem ipsum dolor sit amet, consectetur adipisicing eli.w
--#
--# .flash.warning
--# .light
--# .sign !
--# .message Lorem ipsum dolor sit amet, consectetur adipisicing eli.w
-
diff --git a/app/views/shared/_index_view_edit_destroy_part.html.haml b/app/views/shared/_index_view_edit_destroy_part.html.haml
index 06ec904..00b9e8a 100644
--- a/app/views/shared/_index_view_edit_destroy_part.html.haml
+++ b/app/views/shared/_index_view_edit_destroy_part.html.haml
@@ -1,29 +1,40 @@
-- style = 'width:35px'
+- style = 'width:90px'
+- style = ''
- if !(defined? parent).nil? && !(defined? child).nil?
- %td{ :style => style }
- - if can? :show, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.show"), method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child)
- %td{ :style => style }
- - if can? :edit, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.edit"), method( :"edit_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child)
- %td{ :style => style }
- - if can? :destroy, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.destroy"), method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :method => :delete
- - if child.respond_to?(:move_up?) or child and child.respond_to?(:move_down?)
+ - if can? :show, child
%td{ :style => style }
- - if can? :move_down, child and child.respond_to?(:move_down?) and child.move_down?
- = link_to '&#8681;'.html_safe, method( :"move_lower_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :method => :put
- - if can? :move_up, child and child.respond_to?(:move_up?) and child.move_up?
- = link_to '&#8679;'.html_safe, method( :"move_higher_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :method => :put
+ %a.btn.btn-mini.btn-success{:href => method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child) }
+ %i.icon-info-sign.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.show")
+
+ - if can? :edit, child
+ %td{ :style => style }
+ %a.btn.btn-mini.btn-warning{:href => method( :"edit_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child) }
+ %i.icon-edit.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
+
+ - if can? :destroy, child
+ %td{ :style => style }
+ %a.btn.btn-mini.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.index.actions.confirm_detroy"), "data-method" => "delete", :href => method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :rel => "nofollow"}
+ %i.icon-remove.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.destroy")
- elsif !(defined? child).nil?
- %td{ :style => style }
- - if can? :show, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.show"), method( :"#{child.class.name.underscore}_path" ).(child)
- %td{ :style => style }
- - if can? :edit, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.edit"), method( :"edit_#{child.class.name.underscore}_path" ).(child)
- %td{ :style => style }
- - if can? :destroy, child
- = link_to t("#{child.class.name.underscore.pluralize}.index.actions.destroy"), method( :"#{child.class.name.underscore}_path" ).(child), :method => :delete \ No newline at end of file
+ - if can? :show, child
+ %td{ :style => style }
+ %a.btn.btn-mini.btn-success{:href => method( :"#{child.class.name.underscore}_path" ).(child) }
+ %i.icon-info-sign.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.show")
+
+ - if can? :edit, child
+ %td{ :style => style }
+ %a.btn.btn-mini.btn-warning{:href => method( :"edit_#{child.class.name.underscore}_path" ).(child) }
+ %i.icon-edit.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.edit")
+
+ - if can? :destroy, child
+ %td{ :style => style }
+ %a.btn.btn-mini.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.index.actions.confirm_detroy"), "data-method" => "delete", :href => method( :"#{child.class.name.underscore}_path" ).(child), :rel => "nofollow"}
+ %i.icon-trash.icon-white
+ =t("#{child.class.name.underscore.pluralize}.index.actions.destroy") \ No newline at end of file
diff --git a/app/views/shared/_show_edit_destroy_part.html.haml b/app/views/shared/_show_edit_destroy_part.html.haml
index aff18d1..e82c667 100644
--- a/app/views/shared/_show_edit_destroy_part.html.haml
+++ b/app/views/shared/_show_edit_destroy_part.html.haml
@@ -1,16 +1,20 @@
%p
- if !(defined? parent).nil? && !(defined? child).nil?
- if can? :edit, child
- = link_to t("#{child.class.name.underscore.pluralize}.show.actions.edit"), method( :"edit_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child)
+ %a.btn.btn-warning{:href => method( :"edit_#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child) }
+ %i.icon-edit.icon-white
+ =t("#{child.class.name.underscore.pluralize}.actions.edit")
- if can? :destroy, child
- - if can? :edit, child
- |
- = link_to t("#{child.class.name.underscore.pluralize}.show.actions.destroy"), method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :method => :delete
+ %a.btn.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.actions.confirm_detroy"), "data-method" => "delete", :href => method( :"#{parent.class.name.underscore}_#{child.class.name.underscore}_path" ).(parent, child), :rel => "nofollow"}
+ %i.icon-trash.icon-white
+ =t("#{child.class.name.underscore.pluralize}.actions.destroy")
- elsif !(defined? child).nil?
- if can? :edit, child
- = link_to t("#{child.class.name.underscore.pluralize}.show.actions.edit"), method( :"edit_#{child.class.name.underscore}_path" ).(child)
+ %a.btn.btn-warning{:href => method( :"edit_#{child.class.name.underscore}_path" ).(child) }
+ %i.icon-edit.icon-white
+ =t("#{child.class.name.underscore.pluralize}.actions.edit")
- if can? :destroy, child
- - if can? :edit, child
- |
- = link_to t("#{child.class.name.underscore.pluralize}.show.actions.destroy"), method( :"#{child.class.name.underscore}_path" ).(child), :method => :delete \ No newline at end of file
+ %a.btn.btn-danger{"data-confirm" => t("#{child.class.name.underscore.pluralize}.actions.confirm_detroy"), "data-method" => "delete", :href => method( :"#{child.class.name.underscore}_path" ).(child), :rel => "nofollow"}
+ %i.icon-trash.icon-white
+ =t("#{child.class.name.underscore.pluralize}.actions.destroy") \ No newline at end of file
diff --git a/app/views/shared/_system_message.html.haml b/app/views/shared/_system_message.html.haml
deleted file mode 100644
index 4aabb9c..0000000
--- a/app/views/shared/_system_message.html.haml
+++ /dev/null
@@ -1,10 +0,0 @@
-- if current_user
- .flash.notice#system_message_display
- .light
- .sign i
- .message#system_message This is the place to display incoming calls and other stuff.
-
- = subscribe_to "/users/#{current_user.id}/system_messages"
-
- :javascript
- $('#system_message_display').hide() \ No newline at end of file
diff --git a/app/views/sip_accounts/_form_core.html.haml b/app/views/sip_accounts/_form_core.html.haml
index dbd27fe..495ae84 100644
--- a/app/views/sip_accounts/_form_core.html.haml
+++ b/app/views/sip_accounts/_form_core.html.haml
@@ -1,12 +1,13 @@
.inputs
= f.input :auth_name, :as => :string, :label => t('sip_accounts.form.auth_name.label'), :hint => conditional_hint('sip_accounts.form.auth_name.hint')
= f.input :password, :as => :string, :label => t('sip_accounts.form.password.label'), :hint => conditional_hint('sip_accounts.form.password.hint')
- = f.input :caller_name, :as => :string, :label => t('sip_accounts.form.caller_name.label'), :hint => conditional_hint('sip_accounts.form.caller_name.hint')
+ = f.input :caller_name, :as => :string, :label => t('sip_accounts.form.caller_name.label'), :hint => conditional_hint('sip_accounts.form.caller_name.hint'), :autofocus => true
= f.input :voicemail_pin, :as => :string, :label => t('sip_accounts.form.voicemail_pin.label'), :hint => conditional_hint('sip_accounts.form.voicemail_pin.hint')
= f.input :call_waiting, :label => t('sip_accounts.form.call_waiting.label'), :hint => conditional_hint('sip_accounts.form.call_waiting.hint')
= f.input :clir, :label => t('sip_accounts.form.clir.label'), :hint => conditional_hint('sip_accounts.form.clir.hint')
= f.input :clip, :label => t('sip_accounts.form.clip.label'), :hint => conditional_hint('sip_accounts.form.clip.hint')
- = f.input :hotdeskable, :label => t('sip_accounts.form.hotdeskable.label'), :hint => conditional_hint('sip_accounts.form.hotdeskable.hint')
+ - if @sip_account.sip_accountable_type == 'User'
+ = f.input :hotdeskable, :label => t('sip_accounts.form.hotdeskable.label'), :hint => conditional_hint('sip_accounts.form.hotdeskable.hint')
= f.input :clip_no_screening, :label => t('sip_accounts.form.clip_no_screening.label'), :hint => conditional_hint('sip_accounts.form.clip_no_screening.hint')
- if CallForward.where(:phone_number_id => @sip_account.phone_number_ids).count == 0 || @sip_account.callforward_rules_act_per_sip_account == true
= f.input :callforward_rules_act_per_sip_account, :label => t('sip_accounts.form.callforward_rules_act_per_sip_account.label'), :hint => conditional_hint('sip_accounts.form.callforward_rules_act_per_sip_account.hint')
diff --git a/app/views/sip_accounts/_index_core.html.haml b/app/views/sip_accounts/_index_core.html.haml
index 69c9302..8d9791d 100644
--- a/app/views/sip_accounts/_index_core.html.haml
+++ b/app/views/sip_accounts/_index_core.html.haml
@@ -1,26 +1,24 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('sip_accounts.index.online')
%th= t('sip_accounts.index.caller_name')
%th= t('sip_accounts.index.phone_numbers')
%th= t('phones.name')
-
- - reset_cycle
+ %th{:colspan => '3'}
+
- for sip_account in sip_accounts
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td
- if sip_account.registration
- =image_tag 'icons/phone-down-green-32x.png'
+ %i.icon-ok
- else
- =image_tag 'icons/phone-down-grey-32x.png'
+ %i.icon-thumbs-down
%td
= sip_account.caller_name
- phone_numbers = sip_account.phone_numbers
%td
- if sip_account.phone_numbers.count > 0
= render 'phone_numbers/listing', :phone_numbers => sip_account.phone_numbers.order(:number)
- %br
- = render :partial => 'shared/create_link', :locals => {:parent => sip_account, :child_class => PhoneNumber, :short_link => true}
%td
- sip_account.phones.each do |phone|
diff --git a/app/views/sip_accounts/edit.html.haml b/app/views/sip_accounts/edit.html.haml
index c070ff7..d26b245 100644
--- a/app/views/sip_accounts/edit.html.haml
+++ b/app/views/sip_accounts/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("sip_accounts.edit.page_title")
+- content_for :title, t("sip_accounts.edit.page_title")
= render "form"
diff --git a/app/views/sip_accounts/index.html.haml b/app/views/sip_accounts/index.html.haml
index 1131770..fbdba48 100644
--- a/app/views/sip_accounts/index.html.haml
+++ b/app/views/sip_accounts/index.html.haml
@@ -1,4 +1,4 @@
-- title t("sip_accounts.index.page_title")
+- content_for :title, t("sip_accounts.index.page_title")
- if @sip_accounts.count > 0
= render "index_core", :sip_accounts => @sip_accounts
diff --git a/app/views/sip_accounts/new.html.haml b/app/views/sip_accounts/new.html.haml
index 9d44680..bc4e00b 100644
--- a/app/views/sip_accounts/new.html.haml
+++ b/app/views/sip_accounts/new.html.haml
@@ -1,3 +1,3 @@
-- title t("sip_accounts.new.page_title")
+- content_for :title, t("sip_accounts.new.page_title")
= render "form"
diff --git a/app/views/sip_accounts/show.html.haml b/app/views/sip_accounts/show.html.haml
index c6344cd..4f6244f 100644
--- a/app/views/sip_accounts/show.html.haml
+++ b/app/views/sip_accounts/show.html.haml
@@ -1,4 +1,4 @@
-- title t("sip_accounts.show.page_title")
+- content_for :title, t("sip_accounts.show.page_title")
%p
%strong= t('sip_accounts.show.auth_name') + ":"
diff --git a/app/views/sip_domains/_index_core.html.haml b/app/views/sip_domains/_index_core.html.haml
index 37374f2..d26fd1b 100644
--- a/app/views/sip_domains/_index_core.html.haml
+++ b/app/views/sip_domains/_index_core.html.haml
@@ -1,11 +1,11 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('sip_domains.index.host')
%th= t('sip_domains.index.realm')
- - reset_cycle
+
- for sip_domain in sip_domains
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= sip_domain.host
%td= sip_domain.realm
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => sip_domain} \ No newline at end of file
diff --git a/app/views/sip_domains/edit.html.haml b/app/views/sip_domains/edit.html.haml
index dcf8d6b..adf77ef 100644
--- a/app/views/sip_domains/edit.html.haml
+++ b/app/views/sip_domains/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("sip_domains.edit.page_title")
+- content_for :title, t("sip_domains.edit.page_title")
= render "form"
diff --git a/app/views/sip_domains/index.html.haml b/app/views/sip_domains/index.html.haml
index 6de7f42..3eb0c28 100644
--- a/app/views/sip_domains/index.html.haml
+++ b/app/views/sip_domains/index.html.haml
@@ -1,4 +1,4 @@
-- title t("sip_domains.index.page_title")
+- content_for :title, t("sip_domains.index.page_title")
- if @sip_domains.count > 0
= render "index_core", :sip_domains => @sip_domains
diff --git a/app/views/sip_domains/new.html.haml b/app/views/sip_domains/new.html.haml
index 12ff340..863e680 100644
--- a/app/views/sip_domains/new.html.haml
+++ b/app/views/sip_domains/new.html.haml
@@ -1,3 +1,3 @@
-- title t("sip_domains.new.page_title")
+- content_for :title, t("sip_domains.new.page_title")
= render "form"
diff --git a/app/views/sip_domains/show.html.haml b/app/views/sip_domains/show.html.haml
index e136eaf..b7b74cd 100644
--- a/app/views/sip_domains/show.html.haml
+++ b/app/views/sip_domains/show.html.haml
@@ -1,4 +1,4 @@
-- title t("sip_domains.show.page_title")
+- content_for :title, t("sip_domains.show.page_title")
%p
%strong= t('sip_domains.show.host') + ":"
diff --git a/app/views/softkeys/_index_core.html.haml b/app/views/softkeys/_index_core.html.haml
index fd3dca8..7194379 100644
--- a/app/views/softkeys/_index_core.html.haml
+++ b/app/views/softkeys/_index_core.html.haml
@@ -1,12 +1,12 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('softkeys.index.function')
%th= t('softkeys.index.number')
%th= t('softkeys.index.label')
- - reset_cycle
+
- for softkey in softkeys.order(:position)
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td
=softkey.to_s
%td= softkey.number
diff --git a/app/views/softkeys/edit.html.haml b/app/views/softkeys/edit.html.haml
index 54d53fc..ce45176 100644
--- a/app/views/softkeys/edit.html.haml
+++ b/app/views/softkeys/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("softkeys.edit.page_title")
+- content_for :title, t("softkeys.edit.page_title")
= render "form" \ No newline at end of file
diff --git a/app/views/softkeys/index.html.haml b/app/views/softkeys/index.html.haml
index 8bdc00e..d0b68a9 100644
--- a/app/views/softkeys/index.html.haml
+++ b/app/views/softkeys/index.html.haml
@@ -1,4 +1,4 @@
-- title t("softkeys.index.page_title")
+- content_for :title, t("softkeys.index.page_title")
- if @softkeys.count > 0
= render "index_core", :softkeys => @softkeys
diff --git a/app/views/softkeys/new.html.haml b/app/views/softkeys/new.html.haml
index 593add6..9199a5c 100644
--- a/app/views/softkeys/new.html.haml
+++ b/app/views/softkeys/new.html.haml
@@ -1,3 +1,3 @@
-- title t("softkeys.new.page_title")
+- content_for :title, t("softkeys.new.page_title")
= render "form"
diff --git a/app/views/softkeys/show.html.haml b/app/views/softkeys/show.html.haml
index 9ab4333..d0db111 100644
--- a/app/views/softkeys/show.html.haml
+++ b/app/views/softkeys/show.html.haml
@@ -1,4 +1,4 @@
-- title t("softkeys.show.page_title")
+- content_for :title, t("softkeys.show.page_title")
%p
%strong= t('softkeys.show.function') + ":"
diff --git a/app/views/system_messages/_index_core.html.haml b/app/views/system_messages/_index_core.html.haml
index 157d964..361eb5f 100644
--- a/app/views/system_messages/_index_core.html.haml
+++ b/app/views/system_messages/_index_core.html.haml
@@ -1,11 +1,11 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('system_messages.index.created_at')
%th= t('system_messages.index.content')
- - reset_cycle
+
- for system_message in system_messages
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= system_message.created_at
%td= system_message.content
=render :partial => 'shared/index_view_edit_destroy_part', :locals => {:child => system_message} \ No newline at end of file
diff --git a/app/views/system_messages/index.html.haml b/app/views/system_messages/index.html.haml
index da77e18..ffd3fc3 100644
--- a/app/views/system_messages/index.html.haml
+++ b/app/views/system_messages/index.html.haml
@@ -1,3 +1,3 @@
-- title t("system_messages.index.page_title")
+- content_for :title, t("system_messages.index.page_title")
= render "index_core", :system_messages => @system_messages \ No newline at end of file
diff --git a/app/views/system_messages/new.html.haml b/app/views/system_messages/new.html.haml
index 3afdb24..565f5c5 100644
--- a/app/views/system_messages/new.html.haml
+++ b/app/views/system_messages/new.html.haml
@@ -1,3 +1,3 @@
-- title t("system_messages.new.page_title")
+- content_for :title, t("system_messages.new.page_title")
= render "form"
diff --git a/app/views/system_messages/show.html.haml b/app/views/system_messages/show.html.haml
index 694e4c1..70be6f2 100644
--- a/app/views/system_messages/show.html.haml
+++ b/app/views/system_messages/show.html.haml
@@ -1,4 +1,4 @@
-- title t("system_messages.show.page_title")
+- content_for :title, t("system_messages.show.page_title")
%p
%strong= t('system_messages.show.created_at') + ":"
diff --git a/app/views/tenants/_admin_area.de.html.haml b/app/views/tenants/_admin_area.de.html.haml
deleted file mode 100644
index b9b47d5..0000000
--- a/app/views/tenants/_admin_area.de.html.haml
+++ /dev/null
@@ -1,118 +0,0 @@
-%p
- Sie sind Mitglied der
- = link_to 'Admin Gruppe', tenant_user_group_path(@tenant, @tenant.user_groups.find_by_name('Admins'))
- und haben deshalb besondere Rechte. Aber wie Peter Parker schon sagte: "With great power comes great responsibility."
-
-%p
- Dieser Mandant hat
- = link_to pluralize(@tenant.user_groups.count, 'user group'), tenant_user_groups_path(@tenant)
- - if @tenant.user_groups.count < 5
- = "(#{@tenant.user_groups.order(:name).map{|group| group.to_s }.join(', ')})"
- die in Summe
- = link_to pluralize(@tenant.users.count, 'user'), tenant_users_path(@tenant)
- verwalten.
- Das System kann
- = PhoneModel.count
- verschiedene Telefonmodelle von den folgenden Herstellern verwalten:
- - Manufacturer.all.each do |manufacturer|
- - if manufacturer != Manufacturer.last && manufacturer != Manufacturer.limit(Manufacturer.count - 1).last
- = succeed ', ' do
- =link_to manufacturer, manufacturer_path(manufacturer)
- - elsif manufacturer == Manufacturer.limit(Manufacturer.count - 1).last
- = succeed ' und ' do
- =link_to manufacturer, manufacturer_path(manufacturer)
- - else
- = succeed '.' do
- =link_to manufacturer, manufacturer_path(manufacturer)
-
-%h3 SIP-Konten und Telefone
-
-%table
- %tr{:class => 'even'}
- %th
- %th
- = @tenant
- %th
- Alle Benutzer von
- = "\"#{@tenant}\""
- %tr{:class => 'odd'}
- %td
- SIP-Konten
- %td
- = link_to @tenant.sip_accounts.count.to_s, tenant_sip_accounts_path(@tenant)
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => SipAccount}
- %td= @tenant.users_sip_accounts.count.to_s
- %tr{:class => 'even'}
- %td
- Telefone
- %td
- = link_to @tenant.phones.count.to_s, tenant_phones_path(@tenant)
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Phone}
- %td= @tenant.users_phones.count.to_s
-
-%h3 Allgemein
-
-%table
- %tr{:class => 'even'}
- %th
- Funktion
- %th
- Anzahl
- %th
- %tr{:class => 'odd'}
- %td
- Callthrough
- %td
- = link_to @tenant.callthroughs.count.to_s, tenant_callthroughs_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Callthrough}
- %tr{:class => 'even'}
- %td
- Konferenzen
- %td
- = link_to @tenant.conferences.count.to_s, tenant_conferences_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Conference}
- %tr{:class => 'odd'}
- %td
- Rufgruppen
- %td
- = link_to @tenant.hunt_groups.count.to_s, tenant_hunt_groups_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => HuntGroup}
- %tr{:class => 'even'}
- %td
- Warteschleifen
- %td
- = link_to @tenant.automatic_call_distributors.count.to_s, tenant_automatic_call_distributors_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => AutomaticCallDistributor}
- %tr{:class => 'odd'}
- %td
- Oberflächen-Funktionen
- %td
- = link_to GuiFunction.count.to_s, gui_functions_path
- %td
-
--# Phone books
--#
-- if GuiFunction.display?('show_phone_books_in_user_show_view', current_user)
- - if can?( :index, PhoneBook )
- %h2=t("phone_books.index.page_title")
- = render "phone_books/index_core", :phone_books => @tenant.phone_books
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => PhoneBook}
-
-- if STRICT_INTERNAL_EXTENSION_HANDLING == true
- %h3= t('phone_number_ranges.index.page_title')
-
- - if @tenant.created_at > (Time.now - 15.minutes) && Delayed::Job.count > 0 && @tenant.phone_number_ranges.find_by_name(INTERNAL_EXTENSIONS).try(:phone_numbers).try(:count).to_i == 0
- Der Mandant
- = "\"#{@tenant}\""
- wurde erst vor
- = distance_of_time_in_words_to_now(@tenant.created_at)
- erstellt. Es gibt immer noch nicht abgeschlossene
- = pluralize(Delayed::Job.count, 'Hintergrundprozesse')
- \. Bitte warten Sie noch ein paar Minuten und laden anschließend diese Seite erneut.
- - else
- =render 'phone_number_ranges/index_core', :phone_number_ranges => (@tenant.phone_number_ranges + @tenant.country.phone_number_ranges.where(:name => SERVICE_NUMBERS))
- =render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => PhoneNumberRange}
diff --git a/app/views/tenants/_admin_area.html.haml b/app/views/tenants/_admin_area.html.haml
index d648143..627f221 100644
--- a/app/views/tenants/_admin_area.html.haml
+++ b/app/views/tenants/_admin_area.html.haml
@@ -1,116 +1,32 @@
-%p
- You belong to the
- = link_to 'admin group', tenant_user_group_path(@tenant, @tenant.user_groups.find_by_name('Admins'))
- and therefore have super powers. But always remember Peter Parker's: "With great power comes great responsibility."
+= render :partial => 'tenants/sip_accounts_and_phones', :locals => {:tenant => tenant}
+
+= render :partial => 'users_table', :locals => {:tenant => tenant}
+
+= render :partial => 'user_groups_table', :locals => {:tenant => tenant}
+
+%h2 Features
+= render :partial => 'tenants/table_of_functions', :locals => {:tenant => tenant}
+
+= render :partial => 'tenants/table_of_phone_books', :locals => {:tenant => tenant}
+
+%h2 Gemeinschaft Konfiguration
+= render :partial => 'tenants/gs_parameter_table', :locals => {:tenant => tenant}
%p
- = succeed '.' do
- This tenant has
- = link_to pluralize(@tenant.user_groups.count, 'user group'), tenant_user_groups_path(@tenant)
- - if @tenant.user_groups.count < 5
- = "(#{@tenant.user_groups.order(:name).map{|group| group.to_s }.join(', ')})"
- which handle a total of
- = link_to pluralize(@tenant.users.count, 'user'), tenant_users_path(@tenant)
- This system can setup
+ Das System kann
= PhoneModel.count
- different phone models from the manufacturers
+ verschiedene Telefonmodelle von den folgenden Herstellern verwalten:
- Manufacturer.all.each do |manufacturer|
- if manufacturer != Manufacturer.last && manufacturer != Manufacturer.limit(Manufacturer.count - 1).last
= succeed ', ' do
- =link_to manufacturer, manufacturer_path(manufacturer)
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
- elsif manufacturer == Manufacturer.limit(Manufacturer.count - 1).last
- = succeed ' and ' do
- =link_to manufacturer, manufacturer_path(manufacturer)
+ = succeed ' und ' do
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
- else
= succeed '.' do
- =link_to manufacturer, manufacturer_path(manufacturer)
-
-%h3 SIP-Accounts and Phones
-
-%table
- %tr{:class => 'even'}
- %th
- %th
- = @tenant
- %th
- All users of
- = "\"#{@tenant}\""
- %tr{:class => 'odd'}
- %td
- SIP accounts
- %td
- = link_to @tenant.sip_accounts.count.to_s, tenant_sip_accounts_path(@tenant)
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => SipAccount}
- %td= @tenant.users_sip_accounts.count.to_s
- %tr{:class => 'even'}
- %td
- Phones
- %td
- = link_to @tenant.phones.count.to_s, tenant_phones_path(@tenant)
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Phone}
- %td= @tenant.users_phones.count.to_s
-
-%h3 Misc
-
-%table
- %tr{:class => 'even'}
- %th
- Feature
- %th
- Counter
- %th
- %tr{:class => 'odd'}
- %td
- Callthroughs
- %td
- = link_to @tenant.callthroughs.count.to_s, tenant_callthroughs_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Callthrough}
- %tr{:class => 'even'}
- %td
- Conferences
- %td
- = link_to @tenant.conferences.count.to_s, tenant_conferences_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => Conference}
- %tr{:class => 'odd'}
- %td
- Hunt groups
- %td
- = link_to @tenant.hunt_groups.count.to_s, tenant_hunt_groups_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => HuntGroup}
- %tr{:class => 'even'}
- %td
- ACDs
- %td
- = link_to @tenant.automatic_call_distributors.count.to_s, tenant_automatic_call_distributors_path(@tenant)
- %td
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => AutomaticCallDistributor}
- %tr{:class => 'odd'}
- %td
- GUI functions
- %td
- = link_to GuiFunction.count.to_s, gui_functions_path
- %td
-
--# Phone books
--#
-- if GuiFunction.display?('show_phone_books_in_user_show_view', current_user)
- - if can?( :index, PhoneBook )
- %h2=t("phone_books.index.page_title")
- = render "phone_books/index_core", :phone_books => @tenant.phone_books
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => PhoneBook}
+ =link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + manufacturer, manufacturer_path(manufacturer)
-- if STRICT_INTERNAL_EXTENSION_HANDLING == true
- %h3= t('phone_number_ranges.index.page_title')
+= render :partial => 'call_routes', :locals => {:tenant => tenant}
- - if @tenant.created_at > (Time.now - 15.minutes) && Delayed::Job.count > 0 && @tenant.phone_number_ranges.find_by_name(INTERNAL_EXTENSIONS).try(:phone_numbers).try(:count).to_i == 0
- This tenant was created
- = distance_of_time_in_words_to_now(@tenant.created_at)
- ago. There are still
- = pluralize(Delayed::Job.count, 'background job')
- not finished. This can take a couple of minutes. Please reload this page later.
- - else
- =render 'phone_number_ranges/index_core', :phone_number_ranges => (@tenant.phone_number_ranges + @tenant.country.phone_number_ranges.where(:name => SERVICE_NUMBERS))
- =render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => PhoneNumberRange}
+= render :partial => 'gateways', :locals => {:tenant => tenant, :gateways => gateways} \ No newline at end of file
diff --git a/app/views/tenants/_call_routes.html.haml b/app/views/tenants/_call_routes.html.haml
new file mode 100644
index 0000000..28f84bf
--- /dev/null
+++ b/app/views/tenants/_call_routes.html.haml
@@ -0,0 +1,8 @@
+%h2= t("call_routes.index.page_title")
+
+- if CallRoute.count <= GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = render "call_routes/index_core", :call_routes => CallRoute.all
+ = render :partial => 'shared/create_link', :locals => {:child_class => CallRoute}
+- else
+ %p
+ = link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + t("call_routes.index.page_title"), call_routes_path \ No newline at end of file
diff --git a/app/views/tenants/_form.html.haml b/app/views/tenants/_form.html.haml
index 2ca8a69..1641e78 100644
--- a/app/views/tenants/_form.html.haml
+++ b/app/views/tenants/_form.html.haml
@@ -11,13 +11,13 @@
= f.input :from_field_voicemail_email, :label => t('tenants.form.from_field_voicemail_email.label'), :hint => conditional_hint('tenants.form.from_field_voicemail_email.hint')
= f.input :from_field_pin_change_email, :label => t('tenants.form.from_field_pin_change_email.label'), :hint => conditional_hint('tenants.form.from_field_pin_change_email.hint')
- - if STRICT_INTERNAL_EXTENSION_HANDLING == true || STRICT_DID_HANDLING == true
+ - if GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') == true || GsParameter.get('STRICT_DID_HANDLING') == true
%h2= t('tenants.form.phone_numbers')
%p= t('tenants.form.intro')
- - if STRICT_INTERNAL_EXTENSION_HANDLING == true
+ - if GsParameter.get('STRICT_INTERNAL_EXTENSION_HANDLING') == true
= f.input :internal_extension_ranges, :label => t('tenants.form.internal_extension_ranges.label'), :hint => conditional_hint('tenants.form.internal_extension_ranges.hint')
- - if STRICT_DID_HANDLING == true
+ - if GsParameter.get('STRICT_DID_HANDLING') == true
= f.input :did_list, :label => t('tenants.form.did_list.label'), :hint => conditional_hint('tenants.form.did_list.hint')
.actions
diff --git a/app/views/tenants/_gateways.html.haml b/app/views/tenants/_gateways.html.haml
new file mode 100644
index 0000000..c861ad3
--- /dev/null
+++ b/app/views/tenants/_gateways.html.haml
@@ -0,0 +1,8 @@
+%h2= t("gateways.index.page_title")
+
+- if Gateway.count <= GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = render "gateways/index_core", :gateways => Gateway.all
+ = render :partial => 'shared/create_link', :locals => {:child_class => Gateway}
+- else
+ %p
+ = link_to t("gateways.index.page_title"), gateways_path \ No newline at end of file
diff --git a/app/views/tenants/_gs_parameter_table.html.haml b/app/views/tenants/_gs_parameter_table.html.haml
new file mode 100644
index 0000000..8afdb0e
--- /dev/null
+++ b/app/views/tenants/_gs_parameter_table.html.haml
@@ -0,0 +1,24 @@
+- cache(['gs_parameters_tenant_overview_table', I18n.locale, tenant, GuiFunction.count, GuiFunction.reorder(:updated_at).last, GsParameter.count, GsParameter.reorder(:updated_at).last]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th
+ Funktion
+ %th
+ Anzahl
+ %th
+ Letztes Update
+
+ %tr
+ %td
+ = t("gui_functions.name")
+ %td
+ = link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + GuiFunction.count.to_s, gui_functions_path
+ %td
+ = l GuiFunction.reorder(:updated_at).last.updated_at, :format => :short
+ %tr
+ %td
+ = t("gs_parameters.name")
+ %td
+ = link_to link_to Haml::Engine.new("%i.icon-list").render + ' ' + GsParameter.count.to_s, gs_parameters_path
+ %td
+ = l GsParameter.reorder(:updated_at).last.updated_at, :format => :short
diff --git a/app/views/tenants/_index_core.html.haml b/app/views/tenants/_index_core.html.haml
index 60afeee..721d624 100644
--- a/app/views/tenants/_index_core.html.haml
+++ b/app/views/tenants/_index_core.html.haml
@@ -1,11 +1,11 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('tenants.index.name')
%th= t('tenants.index.description')
- - reset_cycle
+
- for tenant in tenants
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= tenant.name
%td= tenant.description
%td
diff --git a/app/views/tenants/_sip_accounts_and_phones.html.haml b/app/views/tenants/_sip_accounts_and_phones.html.haml
new file mode 100644
index 0000000..bcc2dd6
--- /dev/null
+++ b/app/views/tenants/_sip_accounts_and_phones.html.haml
@@ -0,0 +1,68 @@
+%table{:class => 'table table-striped'}
+ %tr
+ %th
+ %th= t("sip_accounts.index.page_title")
+ %th= t("phones.index.page_title")
+
+ - cache(['tenant_show_admin_area_sip_accounts_and_phones_row', I18n.locale, @tenant, @tenant.sip_accounts.count, @tenant.sip_accounts.reorder(:updated_at).last, @tenant.phones.count, @tenant.phones.reorder(:updated_at).last]) do
+
+ %tr
+ %td= tenant
+ - cache(['tenant_show_admin_area_sip_accounts_table_cell', I18n.locale, @tenant, @tenant.sip_accounts.count, @tenant.sip_accounts.reorder(:updated_at).last]) do
+ %td
+ - if tenant.sip_accounts.any?
+ - if tenant.sip_accounts.count > GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = link_to tenant.sip_accounts.count.to_s, tenant_sip_accounts_path(tenant)
+ - else
+ - tenant.sip_accounts.each do |sip_account|
+ = succeed ', ' do
+ =link_to "#{sip_account.caller_name}", tenant_sip_account_path(tenant,sip_account)
+ - if sip_account.phone_numbers.any?
+ = '[' + truncate(sip_account.phone_numbers.map{|phone_number| phone_number.to_s}.join(', '), :length => 25) + ']'
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => SipAccount}
+
+ - cache(['tenant_show_admin_area_phones_table_cell', I18n.locale, @tenant, @tenant.phones.count, @tenant.phones.reorder(:updated_at).last]) do
+ %td
+ - if tenant.phones.any?
+ - if tenant.phones.count > GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = link_to tenant.phones.count.to_s, tenant_phones_path(tenant)
+ - else
+ - cache(['tenant_show_tenant_phones', I18n.locale, tenant, tenant.phones]) do
+ - tenant.phones.each do |phone|
+ = succeed ', ' do
+ = link_to "#{phone.phone_model.to_s} (#{phone.pretty_mac_address})#{(phone.ip_address.blank? ? '' : " - #{phone.ip_address}")}", tenant_phone_path(tenant, phone)
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => Phone}
+
+ %tr
+ %td= t("users.index.page_title")
+ %td
+ - if tenant.users_sip_accounts.any?
+ - if tenant.users_sip_accounts.count > GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = tenant.users_sip_accounts.count
+ - else
+ - tenant.users_sip_accounts.each do |sip_account|
+ - if sip_account != tenant.users_sip_accounts.last
+ = succeed ', ' do
+ =link_to "#{sip_account.caller_name}", user_sip_account_path(sip_account.sip_accountable,sip_account)
+ - if sip_account.phone_numbers.any?
+ = '[' + truncate(sip_account.phone_numbers.map{|phone_number| phone_number.to_s}.join(', '), :length => 25) + ']'
+ - else
+ =link_to "#{sip_account.caller_name}", user_sip_account_path(sip_account.sip_accountable,sip_account)
+ - if sip_account.phone_numbers.any?
+ = '[' + truncate(sip_account.phone_numbers.map{|phone_number| phone_number.to_s}.join(', '), :length => 25) + ']'
+ - else
+ = "-"
+
+ %td
+ - if tenant.users_phones.any?
+ - if tenant.users_phones.count > GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = tenant.users_phones.count
+ - else
+ - tenant.users_phones.each do |phone|
+ - if phone != tenant.users_phones.last
+ = succeed ', ' do
+ = link_to "#{phone.phone_model.to_s} (#{phone.pretty_mac_address})#{(phone.ip_address.blank? ? '' : " - #{phone.ip_address}")}", user_phone_path(phone.phoneable, phone)
+ - else
+ = link_to "#{phone.phone_model.to_s} (#{phone.pretty_mac_address})#{(phone.ip_address.blank? ? '' : " - #{phone.ip_address}")}", user_phone_path(phone.phoneable, phone)
+ - else
+ = '-'
diff --git a/app/views/tenants/_table_of_functions.html.haml b/app/views/tenants/_table_of_functions.html.haml
new file mode 100644
index 0000000..d7af224
--- /dev/null
+++ b/app/views/tenants/_table_of_functions.html.haml
@@ -0,0 +1,53 @@
+- cache(['table_of_pbx_features', I18n.locale, tenant, tenant.callthroughs.count, tenant.callthroughs.reorder(:updated_at).last, tenant.conferences.count, tenant.conferences.reorder(:updated_at).last, tenant.hunt_groups.count, tenant.hunt_groups.reorder(:updated_at).last, tenant.automatic_call_distributors.count, tenant.automatic_call_distributors.reorder(:updated_at).last]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th
+ Funktion
+ %th
+ Anzahl
+ %th
+ - cache(['table_of_pbx_features_callthroughs_row', I18n.locale, tenant, tenant.callthroughs.count, tenant.callthroughs.reorder(:updated_at).last]) do
+ %tr
+ %td
+ = t("callthroughs.name")
+ %td
+ - if tenant.callthroughs.any?
+ = link_to Haml::Engine.new("%i.icon-list").render + ' ' + tenant.callthroughs.count.to_s, tenant_callthroughs_path(tenant)
+ - else
+ = '-'
+ %td
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => Callthrough}
+ - cache(['table_of_pbx_features_conferences_row', I18n.locale, tenant, tenant.conferences.count, tenant.conferences.reorder(:updated_at).last]) do
+ %tr
+ %td
+ = t("conferences.name")
+ %td
+ - if tenant.conferences.any?
+
+ = link_to Haml::Engine.new("%i.icon-list").render + ' ' + tenant.conferences.count.to_s, tenant_conferences_path(tenant)
+ - else
+ = '-'
+ %td
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => Conference}
+ - cache(['table_of_pbx_features_hunt_groups_row', I18n.locale, tenant, tenant.hunt_groups.count, tenant.hunt_groups.reorder(:updated_at).last]) do
+ %tr
+ %td
+ = t("hunt_groups.name")
+ %td
+ - if tenant.hunt_groups.any?
+ = link_to Haml::Engine.new("%i.icon-list").render + ' ' + tenant.hunt_groups.count.to_s, tenant_hunt_groups_path(tenant)
+ - else
+ = '-'
+ %td
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => HuntGroup}
+ - cache(['table_of_pbx_features_automatic_call_distributors_row', I18n.locale, tenant, tenant.automatic_call_distributors.count, tenant.automatic_call_distributors.reorder(:updated_at).last]) do
+ %tr
+ %td
+ = t("automatic_call_distributors.name")
+ %td
+ - if tenant.automatic_call_distributors.any?
+ = link_to Haml::Engine.new("%i.icon-list").render + ' ' + tenant.automatic_call_distributors.count.to_s, tenant_automatic_call_distributors_path(tenant)
+ - else
+ = '-'
+ %td
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => AutomaticCallDistributor} \ No newline at end of file
diff --git a/app/views/tenants/_table_of_phone_books.html.haml b/app/views/tenants/_table_of_phone_books.html.haml
new file mode 100644
index 0000000..9d9b97c
--- /dev/null
+++ b/app/views/tenants/_table_of_phone_books.html.haml
@@ -0,0 +1,8 @@
+- cache(['user_show_phone_books', I18n.locale, tenant, tenant.phone_books]) do
+ %h2=t("phone_books.index.page_title")
+ -# Phone books
+ -#
+ - if GuiFunction.display?('show_phone_books_in_user_show_view', current_user)
+ - if can?( :index, PhoneBook )
+ = render "phone_books/index_core", :phone_books => tenant.phone_books
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => PhoneBook} \ No newline at end of file
diff --git a/app/views/tenants/_user_groups_table.html.haml b/app/views/tenants/_user_groups_table.html.haml
new file mode 100644
index 0000000..61b3e3d
--- /dev/null
+++ b/app/views/tenants/_user_groups_table.html.haml
@@ -0,0 +1,4 @@
+- if @tenant.user_groups.any?
+ %h2= t("user_groups.index.page_title")
+ = render "user_groups/index_core", :user_groups => tenant.user_groups
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => UserGroup}
diff --git a/app/views/tenants/_users_table.html.haml b/app/views/tenants/_users_table.html.haml
new file mode 100644
index 0000000..850ea5e
--- /dev/null
+++ b/app/views/tenants/_users_table.html.haml
@@ -0,0 +1,7 @@
+%h2= t("users.index.page_title")
+- if @tenant.users.count <= GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
+ = render "users/index_core", :users => tenant.users
+ = render :partial => 'shared/create_link', :locals => {:parent => tenant, :child_class => User}
+- else
+ %p
+ = link_to "Liste aller User.", tenant_users_path(tenant) \ No newline at end of file
diff --git a/app/views/tenants/edit.html.haml b/app/views/tenants/edit.html.haml
index 159f4fd..d2e837d 100644
--- a/app/views/tenants/edit.html.haml
+++ b/app/views/tenants/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("tenants.edit.page_title", :resource => @tenant )
+- content_for :title, t("tenants.edit.page_title", :resource => @tenant )
= render "form"
diff --git a/app/views/tenants/index.html.haml b/app/views/tenants/index.html.haml
index 1783825..9404f17 100644
--- a/app/views/tenants/index.html.haml
+++ b/app/views/tenants/index.html.haml
@@ -1,4 +1,4 @@
-- title t("tenants.index.page_title")
+- content_for :title, t("tenants.index.page_title")
- if @tenants.count > 0
= render "index_core", :tenants => @tenants
diff --git a/app/views/tenants/new.html.haml b/app/views/tenants/new.html.haml
index dca3809..d57ae36 100644
--- a/app/views/tenants/new.html.haml
+++ b/app/views/tenants/new.html.haml
@@ -1,3 +1,3 @@
-- title t("tenants.new.page_title")
+- content_for :title, t("tenants.new.page_title")
= render "form"
diff --git a/app/views/tenants/show.html.haml b/app/views/tenants/show.html.haml
index cb2b895..53d3307 100644
--- a/app/views/tenants/show.html.haml
+++ b/app/views/tenants/show.html.haml
@@ -1,8 +1,5 @@
-- title t("tenants.show.page_title")
+- content_for :title, @tenant.name
-%p
- %strong= t('tenants.show.name') + ":"
- = @tenant.name
- if !@tenant.description.blank?
%p
%strong= t('tenants.show.description') + ":"
@@ -10,5 +7,5 @@
= render :partial => 'shared/show_edit_destroy_part', :locals => { :child => @tenant }
-- if @tenant.user_groups.where(:name => 'Admins').count > 0 && @tenant.user_groups.where(:name => 'Admins').first.users.include?(current_user)
- = render 'admin_area' \ No newline at end of file
+- if @tenant.user_groups.where(:name => 'Admins').any? && @tenant.user_groups.where(:name => 'Admins').first.users.include?(current_user)
+ = render :partial => 'admin_area', :locals => { :tenant => @tenant, :gateways => @gateways} \ No newline at end of file
diff --git a/app/views/trigger/fax.html.erb b/app/views/trigger/fax.html.erb
new file mode 100644
index 0000000..822b2cb
--- /dev/null
+++ b/app/views/trigger/fax.html.erb
@@ -0,0 +1,2 @@
+<h1>Trigger#fax</h1>
+<p>Find me in app/views/trigger/fax.html.erb</p>
diff --git a/app/views/trigger/voicemail.html.erb b/app/views/trigger/voicemail.html.erb
new file mode 100644
index 0000000..9bafe17
--- /dev/null
+++ b/app/views/trigger/voicemail.html.erb
@@ -0,0 +1,4 @@
+<h1>Trigger#voicemail</h1>
+<p>Find me in app/views/trigger/voicemail.html.erb</p>
+
+<%= debug(params) %>
diff --git a/app/views/user_group_memberships/_index_core.html.haml b/app/views/user_group_memberships/_index_core.html.haml
index 3c3cebe..5e6536b 100644
--- a/app/views/user_group_memberships/_index_core.html.haml
+++ b/app/views/user_group_memberships/_index_core.html.haml
@@ -1,12 +1,12 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('user_group_memberships.index.tenant')
%th= t('user_group_memberships.index.user_group')
%th= t('user_group_memberships.index.user')
- - reset_cycle
+
- for user_group_membership in user_group_memberships
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= user_group_membership.user_group.tenant
%td= user_group_membership.user_group
%td= user_group_membership.user
diff --git a/app/views/user_group_memberships/edit.html.haml b/app/views/user_group_memberships/edit.html.haml
index 2080c87..118aacd 100644
--- a/app/views/user_group_memberships/edit.html.haml
+++ b/app/views/user_group_memberships/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("user_group_memberships.edit.page_title", :resource => @user_group_membership)
+- content_for :title, t("user_group_memberships.edit.page_title", :resource => @user_group_membership)
= render "form"
diff --git a/app/views/user_group_memberships/index.html.haml b/app/views/user_group_memberships/index.html.haml
index 1d7927b..b12e682 100644
--- a/app/views/user_group_memberships/index.html.haml
+++ b/app/views/user_group_memberships/index.html.haml
@@ -1,4 +1,4 @@
-- title t("user_group_memberships.index.page_title")
+- content_for :title, t("user_group_memberships.index.page_title")
- if @user_group_memberships.count > 0
= render "index_core", :user_group_memberships => @user_group_memberships
diff --git a/app/views/user_group_memberships/new.html.haml b/app/views/user_group_memberships/new.html.haml
index 9d59fdd..8901058 100644
--- a/app/views/user_group_memberships/new.html.haml
+++ b/app/views/user_group_memberships/new.html.haml
@@ -1,3 +1,3 @@
-- title t("user_group_memberships.new.page_title")
+- content_for :title, t("user_group_memberships.new.page_title")
= render "form"
diff --git a/app/views/user_group_memberships/show.html.haml b/app/views/user_group_memberships/show.html.haml
index 0e5cfab..418a266 100644
--- a/app/views/user_group_memberships/show.html.haml
+++ b/app/views/user_group_memberships/show.html.haml
@@ -1,4 +1,4 @@
-- title t("user_group_memberships.show.page_title")
+- content_for :title, t("user_group_memberships.show.page_title")
%p
%strong= t('user_group_memberships.show.user') + ":"
diff --git a/app/views/user_groups/_index_core.html.haml b/app/views/user_groups/_index_core.html.haml
index d2b6e88..941f9fa 100644
--- a/app/views/user_groups/_index_core.html.haml
+++ b/app/views/user_groups/_index_core.html.haml
@@ -1,24 +1,28 @@
-%table
- %tr
- %th= t('user_groups.index.name')
- %th= t('user_groups.index.description')
- - if @user
- %th= t('user_groups.index.tenant_id')
- - else
- %th= t('user_groups.index.members')
-
- - reset_cycle
- - for user_group in user_groups
- %tr{:class => cycle('odd', 'even')}
- %td= user_group.name
- %td= user_group.description
+- cache(['user_groups_table', I18n.locale, current_user, @user, user_groups, User.order(:updated_at).last, User.count, UserGroupMembership.count, GsParameter.get('NUMBER_OF_SHOWN_ITEMS')]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th= t('user_groups.index.name')
+ - if user_groups.pluck(:description).uniq != [nil]
+ %th= t('user_groups.index.description')
- if @user
- %td= user_group.tenant
+ %th= t('user_groups.index.tenant_id')
- else
- %td
- =render 'users/listing', :users => user_group.users
- - if user_group.users.count > 1
- %br
- = render :partial => 'shared/create_link', :locals => {:parent => user_group, :child_class => UserGroupMembership}
+ %th= t('user_groups.index.members')
+ %th{:colspan => '3'}
+
+ - for user_group in user_groups
+ %tr
+ %td= user_group.name
+ - if user_groups.pluck(:description).uniq != [nil]
+ %td= user_group.description
+ - if @user
+ %td= user_group.tenant
+ - else
+ %td
+ =render 'users/listing', :users => user_group.users
+ - if user_group.users.any?
+ %br
+ - if (user_group.tenant.user_ids - user_group.user_ids).any?
+ = render :partial => 'shared/create_link', :locals => {:parent => user_group, :child_class => UserGroupMembership}
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => user_group.tenant, :child => user_group}
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => user_group.tenant, :child => user_group}
diff --git a/app/views/user_groups/edit.html.haml b/app/views/user_groups/edit.html.haml
index 35514e0..4d263a4 100644
--- a/app/views/user_groups/edit.html.haml
+++ b/app/views/user_groups/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("user_groups.edit.page_title", :resource => @user_group)
+- content_for :title, t("user_groups.edit.page_title", :resource => @user_group)
= render "form"
diff --git a/app/views/user_groups/index.html.haml b/app/views/user_groups/index.html.haml
index 545b838..7240f5f 100644
--- a/app/views/user_groups/index.html.haml
+++ b/app/views/user_groups/index.html.haml
@@ -1,4 +1,4 @@
-- title t("user_groups.index.page_title")
+- content_for :title, t("user_groups.index.page_title")
- if @user_groups.count > 0
= render "index_core", :user_groups => @user_groups
diff --git a/app/views/user_groups/new.html.haml b/app/views/user_groups/new.html.haml
index dfef18e..3c5920f 100644
--- a/app/views/user_groups/new.html.haml
+++ b/app/views/user_groups/new.html.haml
@@ -1,3 +1,3 @@
-- title t("user_groups.new.page_title")
+- content_for :title, t("user_groups.new.page_title")
= render "form"
diff --git a/app/views/user_groups/show.html.haml b/app/views/user_groups/show.html.haml
index 00bdeb7..fe5b745 100644
--- a/app/views/user_groups/show.html.haml
+++ b/app/views/user_groups/show.html.haml
@@ -1,4 +1,4 @@
-- title t("user_groups.show.page_title")
+- content_for :title, t("user_groups.show.page_title")
%p
%strong= t('user_groups.show.name') + ":"
diff --git a/app/views/users/_conferences.html.haml b/app/views/users/_conferences.html.haml
new file mode 100644
index 0000000..b9592b6
--- /dev/null
+++ b/app/views/users/_conferences.html.haml
@@ -0,0 +1,7 @@
+-# Conferences
+-#
+- if (can?( :index, Conference ) && user.conferences.count > 0 ) || can?( :create, Conference )
+ %h2= t('conferences.index.page_title')
+ - if can?( :index, Conference ) && user.conferences.count > 0
+ = render "conferences/index_core", :conferences => user.conferences
+ = render :partial => 'shared/create_link', :locals => {:parent => user, :child_class => Conference} \ No newline at end of file
diff --git a/app/views/users/_fax_accounts.html.haml b/app/views/users/_fax_accounts.html.haml
new file mode 100644
index 0000000..044b8f9
--- /dev/null
+++ b/app/views/users/_fax_accounts.html.haml
@@ -0,0 +1,7 @@
+-# FaxAccount
+-#
+- if (can?( :index, FaxAccount ) && user.fax_accounts.count > 0 ) || can?( :create, FaxAccount )
+ %h2= t('fax_accounts.index.page_title')
+ - if can?( :index, FaxAccount ) && user.fax_accounts.count > 0
+ = render "fax_accounts/index_core", {:fax_accounts => user.fax_accounts, :fax_accountable => user}
+ = render :partial => 'shared/create_link', :locals => {:parent => user, :child_class => FaxAccount} \ No newline at end of file
diff --git a/app/views/users/_form_core.html.haml b/app/views/users/_form_core.html.haml
index 8e18d12..24b15f5 100644
--- a/app/views/users/_form_core.html.haml
+++ b/app/views/users/_form_core.html.haml
@@ -1,6 +1,6 @@
.inputs
- if GuiFunction.display?('name_data_fields_in_user_edit_form', current_user)
- = f.input :male, :collection => [[true, t('users.form.gender.male')], [false, t('users.form.gender.female')]], :label_method => :last, :value_method => :first, :label => t('users.form.male.label'), :hint => conditional_hint('users.form.gender.hint'), :label => t('users.form.gender.label'), :as => :radio
+ = f.input :male, :collection => [[true, t('users.form.gender.male')], [false, t('users.form.gender.female')]], :label_method => :last, :value_method => :first, :label => t('users.form.male.label'), :hint => conditional_hint('users.form.gender.hint'), :label => t('users.form.gender.label'), :as => :radio_buttons
= f.input :first_name, :label => t('users.form.first_name.label'), :hint => conditional_hint('users.form.first_name.hint'), :autofocus => true
= f.input :middle_name, :label => t('users.form.middle_name.label'), :hint => conditional_hint('users.form.middle_name.hint')
= f.input :last_name, :label => t('users.form.last_name.label'), :hint => conditional_hint('users.form.last_name.hint')
diff --git a/app/views/users/_index_core.html.haml b/app/views/users/_index_core.html.haml
index 51c15de..7f2251a 100644
--- a/app/views/users/_index_core.html.haml
+++ b/app/views/users/_index_core.html.haml
@@ -1,18 +1,28 @@
-%table
- %tr
- %th
- %th= t('users.index.user_name')
- %th= t('users.index.email')
- %th= t('users.index.first_name')
- %th= t('users.index.last_name')
-
- - reset_cycle
- - for user in users
- %tr{:class => cycle('odd', 'even')}
- %td
- = image_tag user.image_url(:mini).to_s if user.image_url(:mini)
- %td= user.user_name
- %td= user.email
- %td= user.first_name
- %td= user.last_name
- =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @tenant, :child => user} \ No newline at end of file
+- cache(['user_table_row_inner_td', I18n.locale, current_user, users.reorder(:updated_at).last, users.count, GsParameter.get('NUMBER_OF_SHOWN_ITEMS')]) do
+ %table{:class => 'table table-striped'}
+ %tr
+ %th
+ %th= t('users.index.user_name')
+ %th= t('users.index.email')
+ %th= t('users.index.first_name')
+ %th= t('users.index.last_name')
+ %th{:colspan => '3'}
+
+ - for user in users
+ - cache(['user_table_row', I18n.locale, current_user, user]) do
+ %tr
+ %td
+ - if user.image?
+ =image_tag(user.image_url(:mini).to_s, :class => 'img-rounded')
+ - else
+ - if user.male?
+ = image_tag 'icons/user-male-16x.png', :class => 'img-rounded'
+ - else
+ = image_tag 'icons/user-female-16x.png', :class => 'img-rounded'
+ %td= user.user_name
+ %td
+ - if !user.email.blank?
+ = mail_to user.email, (Haml::Engine.new("%i.icon-envelope").render + ' ' + user.email)
+ %td= user.first_name
+ %td= user.last_name
+ =render :partial => 'shared/index_view_edit_destroy_part', :locals => {:parent => @tenant, :child => user} \ No newline at end of file
diff --git a/app/views/users/_listing.html.haml b/app/views/users/_listing.html.haml
index 0a97ad1..9b7b653 100644
--- a/app/views/users/_listing.html.haml
+++ b/app/views/users/_listing.html.haml
@@ -1,8 +1,8 @@
- amount_of_users = users.count
- if amount_of_users > 0
- - if amount_of_users < 30
+ - if amount_of_users < GsParameter.get('NUMBER_OF_SHOWN_ITEMS')
= users.map{|user| user}.join(', ')
- else
- = users.limit(15).map{|user| user}.join(', ') + ', '
+ = users.limit((GsParameter.get('NUMBER_OF_SHOWN_ITEMS') / 2).floor).map{|user| user}.join(', ') + ', '
= '[...]'
- = users.offset(amount_of_users - 15).map{|user| user}.join(', ') \ No newline at end of file
+ = users.offset(amount_of_users - (GsParameter.get('NUMBER_OF_SHOWN_ITEMS') / 2).floor).map{|user| user}.join(', ') \ No newline at end of file
diff --git a/app/views/users/_phone_books.html.haml b/app/views/users/_phone_books.html.haml
new file mode 100644
index 0000000..4943bc6
--- /dev/null
+++ b/app/views/users/_phone_books.html.haml
@@ -0,0 +1,7 @@
+-# Phone books
+-#
+- if GuiFunction.display?('show_phone_books_in_user_show_view', current_user)
+ - if can?( :index, PhoneBook )
+ %h2=t("phone_books.index.page_title")
+ = render "phone_books/index_core", :phone_books => phone_books
+ = render :partial => 'shared/create_link', :locals => {:parent => user, :child_class => PhoneBook} \ No newline at end of file
diff --git a/app/views/users/_phones.html.haml b/app/views/users/_phones.html.haml
new file mode 100644
index 0000000..e001eae
--- /dev/null
+++ b/app/views/users/_phones.html.haml
@@ -0,0 +1,7 @@
+-# Phones
+-#
+- if (can?( :index, Phone, :phoneable => user ) && user.phones.count > 0 ) || can?( :create, Phone, :phoneable => user )
+ %h2= t('phones.index.page_title')
+ - if can?( :index, Phone, :phoneable => user ) && user.phones.count > 0
+ = render "phones/index_core", :phones => user.phones
+ = render :partial => 'shared/create_link', :locals => {:parent => user, :child_class => Phone} \ No newline at end of file
diff --git a/app/views/users/_sip_accounts.html.haml b/app/views/users/_sip_accounts.html.haml
new file mode 100644
index 0000000..1861105
--- /dev/null
+++ b/app/views/users/_sip_accounts.html.haml
@@ -0,0 +1,7 @@
+-# SIP accounts
+-#
+- if (can?( :index, SipAccount ) && user.sip_accounts.count > 0 ) || can?( :create, SipAccount )
+ %h2= t('sip_accounts.index.page_title')
+ - if can?( :index, SipAccount ) && user.sip_accounts.count > 0
+ = render "sip_accounts/index_core", :sip_accounts => user.sip_accounts
+ = render :partial => 'shared/create_link', :locals => {:parent => user, :child_class => SipAccount} \ No newline at end of file
diff --git a/app/views/users/_tenants.html.haml b/app/views/users/_tenants.html.haml
new file mode 100644
index 0000000..49a2d9b
--- /dev/null
+++ b/app/views/users/_tenants.html.haml
@@ -0,0 +1,5 @@
+-# Tenants
+-#
+- if can?( :index, Tenant ) && user.tenants.count > 1
+ %h2=t("tenants.index.page_title")
+ = render "tenants/index_core", :tenants => user.tenants \ No newline at end of file
diff --git a/app/views/users/_user_groups.html.haml b/app/views/users/_user_groups.html.haml
new file mode 100644
index 0000000..81191ae
--- /dev/null
+++ b/app/views/users/_user_groups.html.haml
@@ -0,0 +1,7 @@
+-# User groups (only if the current user can edit or destroy them)
+-#
+- if user.user_groups.map{ |x| can?( :edit, x ) || can?( :destroy, x ) }.include?(true)
+ - if can?( :index, UserGroup )
+ %h2=t("user_groups.index.page_title")
+ - if user.user_groups.count > 0
+ = render "user_groups/index_core", :user_groups => user.user_groups.where(:tenant_id => tenant.id).order(:name)
diff --git a/app/views/users/edit.html.haml b/app/views/users/edit.html.haml
index 96272f5..ed79b2c 100644
--- a/app/views/users/edit.html.haml
+++ b/app/views/users/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("users.edit.page_title", :resource => @user)
+- content_for :title, t("users.edit.page_title", :resource => @user)
= render "form"
diff --git a/app/views/users/index.html.haml b/app/views/users/index.html.haml
index 892e035..8a3d1fc 100644
--- a/app/views/users/index.html.haml
+++ b/app/views/users/index.html.haml
@@ -1,4 +1,4 @@
-- title t("users.index.page_title")
+- content_for :title, t("users.index.page_title")
- if @users.count > 0
= render "index_core", :users => @users
diff --git a/app/views/users/new.html.haml b/app/views/users/new.html.haml
index a014611..64fe55f 100644
--- a/app/views/users/new.html.haml
+++ b/app/views/users/new.html.haml
@@ -1,3 +1,3 @@
-- title t("users.new.page_title")
+- content_for :title, t("users.new.page_title")
= render "form"
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 7730447..4c39fd1 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -1,96 +1,60 @@
-- title "User: #{@user}"
+- content_for :title, "User: #{@user}"
-#user-show
- %aside
- = image_tag @user.image_url(:small).to_s, class: 'display' if @user.image? && @user.image_url(:small)
- %p
- %strong= t('users.show.user_name') + ":"
- = @user.user_name
- %p
- %strong= t('users.show.email') + ":"
- = @user.email
-
- %p.controls
- = render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @tenant, :child => @user }
-
- - @user.sip_accounts.each do |sip_account|
- - phone_number = sip_account.phone_numbers.order(:number).last
- - if phone_number && !phone_number.number.blank? && phone_number.number[0] != '+'
- %p
- %strong= sip_account.phone_numbers.order(:number).last.number
- %p
- =link_to t("call_histories.index.page_title"), sip_account_call_histories_path(sip_account)
- %br
- =link_to t("voicemail_messages.index.page_title"), sip_account_voicemail_messages_path(sip_account)
- %br
- =link_to t("call_forwards.index.page_title"), phone_number_call_forwards_path(phone_number)
- %br
- =link_to t("voicemail_settings.index.page_title"), sip_account_voicemail_settings_path(sip_account)
- %br
- =link_to t("softkeys.index.page_title"), sip_account_softkeys_path(sip_account)
- %br
- =link_to t("ringtones.show.page_title"), phone_number_ringtones_path(phone_number)
-
- - if @user.conferences.any?
+.row
+ .span3
+ - cache(['user_show_aside', I18n.locale, @user, @user.sip_accounts, @user.conferences]) do
+ = image_tag @user.image_url(:small).to_s, :class => 'img-rounded' if @user.image? && @user.image_url(:small)
+ %p
+ %strong= t('users.show.user_name') + ":"
+ = @user.user_name
%p
- %strong= t("conferences.index.page_title")
- - @user.conferences.each do |conference|
+ %strong= t('users.show.email') + ":"
+ = @user.email
+
+ %p.controls
+ = render :partial => 'shared/show_edit_destroy_part', :locals => { :parent => @tenant, :child => @user }
+
+ - @user.sip_accounts.each do |sip_account|
+ - phone_number = sip_account.phone_numbers.order(:number).last
+ - if phone_number && !phone_number.number.blank? && phone_number.number[0] != '+'
+ %p
+ %strong= sip_account.phone_numbers.order(:number).last.number
+ %p
+ =link_to t("call_histories.index.page_title"), sip_account_call_histories_path(sip_account)
+ %br
+ =link_to t("voicemail_messages.index.page_title"), sip_account_voicemail_messages_path(sip_account)
+ %br
+ =link_to t("call_forwards.index.page_title"), phone_number_call_forwards_path(phone_number)
+ %br
+ =link_to t("voicemail_settings.index.page_title"), sip_account_voicemail_settings_path(sip_account)
+ %br
+ =link_to t("softkeys.index.page_title"), sip_account_softkeys_path(sip_account)
+ %br
+ =link_to t("ringtones.show.page_title"), phone_number_ringtones_path(phone_number)
+
+ - if @user.conferences.any?
%p
- =link_to conference, edit_user_conference_path(@user, conference)
-
+ %strong= t("conferences.index.page_title")
+ - @user.conferences.each do |conference|
+ %p
+ =link_to conference, edit_user_conference_path(@user, conference)
- %section
- -# Phone books
- -#
- - if GuiFunction.display?('show_phone_books_in_user_show_view', current_user)
- - if can?( :index, PhoneBook )
- %h2=t("phone_books.index.page_title")
- = render "phone_books/index_core", :phone_books => @phone_books
- = render :partial => 'shared/create_link', :locals => {:parent => @user, :child_class => PhoneBook}
- -# User groups (only if the current user can edit or destroy them)
- -#
- - if @user.user_groups.map{ |x| can?( :edit, x ) || can?( :destroy, x ) }.include?(true)
- - if can?( :index, UserGroup )
- %h2=t("user_groups.index.page_title")
- - if @user.user_groups.count > 0
- = render "user_groups/index_core", :user_groups => @user.user_groups.where(:tenant_id => @tenant.id).order(:name)
- = render :partial => 'shared/create_link', :locals => {:parent => @tenant, :child_class => UserGroup}
+ .span9
+ = render :partial => 'phone_books', :locals => {:user => @user, :phone_books => @phone_books}
- -# SIP accounts
- -#
- - if (can?( :index, SipAccount ) && @user.sip_accounts.count > 0 ) || can?( :create, SipAccount )
- %h2= t('sip_accounts.index.page_title')
- - if can?( :index, SipAccount ) && @user.sip_accounts.count > 0
- = render "sip_accounts/index_core", :sip_accounts => @user.sip_accounts
- = render :partial => 'shared/create_link', :locals => {:parent => @user, :child_class => SipAccount}
+ - if current_user.user_groups.where(:name => 'Admins').any?
+ - cache(['user_show_user_groups_overview', I18n.locale, @user, @user.user_groups]) do
+ = render :partial => 'user_groups', :locals => {:user => @user, :tenant => @tenant}
- -# Phones
- -#
- - if (can?( :index, Phone, :phoneable => @user ) && @user.phones.count > 0 ) || can?( :create, Phone, :phoneable => @user )
- %h2= t('phones.index.page_title')
- - if can?( :index, Phone, :phoneable => @user ) && @user.phones.count > 0
- = render "phones/index_core", :phones => @user.phones
- = render :partial => 'shared/create_link', :locals => {:parent => @user, :child_class => Phone}
+ - cache(['user_show_sip_accounts_overview', I18n.locale, @user, @user.sip_accounts]) do
+ = render :partial => 'sip_accounts', :locals => {:user => @user}
- -# FaxAccount
- -#
- - if (can?( :index, FaxAccount ) && @user.fax_accounts.count > 0 ) || can?( :create, FaxAccount )
- %h2= t('fax_accounts.index.page_title')
- - if can?( :index, FaxAccount ) && @user.fax_accounts.count > 0
- = render "fax_accounts/index_core", {:fax_accounts => @user.fax_accounts, :fax_accountable => @user}
- = render :partial => 'shared/create_link', :locals => {:parent => @user, :child_class => FaxAccount}
+ - cache(['user_show_phones_overview', I18n.locale, @user, @user.phones]) do
+ = render :partial => 'phones', :locals => {:user => @user}
- -# Conferences
- -#
- - if (can?( :index, Conference ) && @user.conferences.count > 0 ) || can?( :create, Conference )
- %h2= t('conferences.index.page_title')
- - if can?( :index, Conference ) && @user.conferences.count > 0
- = render "conferences/index_core", :conferences => @user.conferences
- = render :partial => 'shared/create_link', :locals => {:parent => @user, :child_class => Conference}
+ - cache(['user_show_fax_accounts_overview', I18n.locale, @user, @user.fax_accounts]) do
+ = render :partial => 'fax_accounts', :locals => {:user => @user}
- -# Tenants
- -#
- - if can?( :index, Tenant ) && @user.tenants.count > 1
- %h2=t("tenants.index.page_title")
- = render "tenants/index_core", :tenants => @user.tenants \ No newline at end of file
+ - cache(['user_show_conferences_overview', I18n.locale, @user, @user.conferences]) do
+ = render :partial => 'conferences', :locals => {:user => @user}
diff --git a/app/views/voicemail_messages/_index_core.html.haml b/app/views/voicemail_messages/_index_core.html.haml
index b8e47af..ded7ea0 100644
--- a/app/views/voicemail_messages/_index_core.html.haml
+++ b/app/views/voicemail_messages/_index_core.html.haml
@@ -1,10 +1,10 @@
= form_tag(destroy_multiple_sip_account_voicemail_messages_path(@sip_account), :method => :delete, :id => 'voicemail_message_form') do
%header.entries-nav= render :partial => "voicemail_messages/navigation"
.content
- %table
- - reset_cycle
+ %table{:class => 'table table-striped'}
+
- for voicemail_message in voicemail_messages
- %tr.voicemail-messages-entry{:class => cycle('odd', 'even'), :id => "message_#{voicemail_message.uuid}"}
+ %tr.voicemail-messages-entry{:id => "message_#{voicemail_message.uuid}"}
%td.select_box= check_box_tag("selected_uuids[]", voicemail_message.uuid, false, :uuid => "select_item_#{voicemail_message.uuid}", :class => 'select_item')
%td.time
.voicemail-received
@@ -40,5 +40,6 @@
= link_to t('voicemail_messages.index.actions.destroy'), sip_account_voicemail_message_path(@sip_account, voicemail_message), :method => :delete
%footer.entries-nav= render :partial => "voicemail_messages/navigation"
+ = link_to Haml::Engine.new("%i.icon-remove").render + ' test ', root_url
= image_submit_tag('icons/cross-16x.png', :confirm => t("voicemail_messages.index.actions.confirm_selected"))
= t("voicemail_messages.index.actions.destroy_multiple")
diff --git a/app/views/voicemail_messages/index.html.haml b/app/views/voicemail_messages/index.html.haml
index 53f8090..53ff745 100644
--- a/app/views/voicemail_messages/index.html.haml
+++ b/app/views/voicemail_messages/index.html.haml
@@ -1,6 +1,6 @@
- if @type
- - title t("voicemail_messages.index.page_title_#{@type}")
+ - content_for :title, t("voicemail_messages.index.page_title_#{@type}")
- else
- - title t("voicemail_messages.index.page_title")
+ - content_for :title, t("voicemail_messages.index.page_title")
= render "index_core", :voicemail_messages => @voicemail_messages
diff --git a/app/views/voicemail_settings/edit.html.haml b/app/views/voicemail_settings/edit.html.haml
index 6bd7031..56e5765 100644
--- a/app/views/voicemail_settings/edit.html.haml
+++ b/app/views/voicemail_settings/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("voicemail_settings.edit.page_title")
+- content_for :title, t("voicemail_settings.edit.page_title")
= render "form"
diff --git a/app/views/voicemail_settings/show.html.haml b/app/views/voicemail_settings/show.html.haml
index 30e12d0..e156d7b 100644
--- a/app/views/voicemail_settings/show.html.haml
+++ b/app/views/voicemail_settings/show.html.haml
@@ -1,4 +1,4 @@
-- title t("voicemail_settings.show.page_title")
+- content_for :title, t("voicemail_settings.show.page_title")
%p
%strong= t('voicemail_settings.show.greeting_path') + ":"
diff --git a/app/views/whitelists/_index_core.html.haml b/app/views/whitelists/_index_core.html.haml
index b4c5b0c..3333169 100644
--- a/app/views/whitelists/_index_core.html.haml
+++ b/app/views/whitelists/_index_core.html.haml
@@ -1,11 +1,11 @@
-%table
+%table{:class => 'table table-striped'}
%tr
%th= t('whitelists.index.name')
%th= t('whitelists.index.phone_numbers')
- - reset_cycle
+
- for whitelist in whitelists
- %tr{:class => cycle('odd', 'even')}
+ %tr
%td= whitelist.name || '-'
%td
= render 'phone_numbers/listing', :phone_numbers => whitelist.phone_numbers
diff --git a/app/views/whitelists/edit.html.haml b/app/views/whitelists/edit.html.haml
index 9f8af90..9adcc58 100644
--- a/app/views/whitelists/edit.html.haml
+++ b/app/views/whitelists/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("whitelists.edit.page_title")
+- content_for :title, t("whitelists.edit.page_title")
= render "form"
diff --git a/app/views/whitelists/index.html.haml b/app/views/whitelists/index.html.haml
index 0873189..52ab453 100644
--- a/app/views/whitelists/index.html.haml
+++ b/app/views/whitelists/index.html.haml
@@ -1,4 +1,4 @@
-- title t("whitelists.index.page_title")
+- content_for :title, t("whitelists.index.page_title")
- if @whitelists.count > 0
= render "index_core", :whitelists => @whitelists
diff --git a/app/views/whitelists/new.html.haml b/app/views/whitelists/new.html.haml
index f1101ad..7086cfd 100644
--- a/app/views/whitelists/new.html.haml
+++ b/app/views/whitelists/new.html.haml
@@ -1,3 +1,3 @@
-- title t("whitelists.new.page_title")
+- content_for :title, t("whitelists.new.page_title")
= render "form"
diff --git a/app/views/whitelists/show.html.haml b/app/views/whitelists/show.html.haml
index 77652f9..054afc5 100644
--- a/app/views/whitelists/show.html.haml
+++ b/app/views/whitelists/show.html.haml
@@ -1,4 +1,4 @@
-- title t("whitelists.show.page_title")
+- content_for :title, t("whitelists.show.page_title")
%p
%strong= t('whitelists.show.name') + ":"
diff --git a/config/application.rb b/config/application.rb
index d09cf24..ad58092 100644
--- a/config/application.rb
+++ b/config/application.rb
@@ -4,7 +4,7 @@ require 'rails/all'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
- Bundler.require *Rails.groups(:assets => %w(development test))
+ Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
@@ -17,23 +17,24 @@ module Gemeinschaft42c
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
+ config.autoload_paths += %W(#{config.root}/lib)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
-
+
# --- rather use Apache + Passenger for SSL -----{
#config.plugins = [ :exception_notification, :ssl_requirement, :all ]
-
+
#config.middleware.insert_before ActionDispatch::Static, "Rack::SSL"
#config.middleware.insert_before ActionDispatch::Static, Rack::SSL, :exclude => proc { |env| env['HTTPS'] != 'on' }
#config.force_ssl = true
-
+
#require 'rack/ssl'
#config.middleware.use Rack::SSL
# -----------------------------------------------}
-
-
+
+
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
@@ -58,7 +59,7 @@ module Gemeinschaft42c
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
-
+
# Load the PhoneControllers
config.autoload_paths += %W(#{config.root}/lib/phone_controllers)
end
diff --git a/config/database.yml b/config/database.yml
index bd1748e..364cbdb 100644
--- a/config/database.yml
+++ b/config/database.yml
@@ -1,22 +1,44 @@
-development:
- adapter: mysql2
+<% system_odbc_ini_file = '/var/lib/freeswitch/.odbc.ini' %>
+<% if !File.exists?(system_odbc_ini_file) %>
+development:
+ adapter: sqlite3
+ database: db/development.sqlite3
+ pool: 5
+ timeout: 5000
+
+production:
+ adapter: mysql2
encoding: utf8
database: gemeinschaft
- pool: 5
+ pool: 10
username: gemeinschaft
password: gemeinschaft
socket: /var/run/mysqld/mysqld.sock
- reconnect: true
+ reconnect: true
+<% else %>
+<% system_odbc_configuration = IniFile.load(system_odbc_ini_file) %>
+<% if !system_odbc_configuration['gemeinschaft']['DATABASE'].blank? && !system_odbc_configuration['gemeinschaft']['USER'].blank? %>
+development:
+ adapter: mysql2
+ encoding: utf8
+ database: <%= system_odbc_configuration['gemeinschaft']['DATABASE'] %>
+ pool: 5
+ username: <%= system_odbc_configuration['gemeinschaft']['USER'] %>
+ password: <%= system_odbc_configuration['gemeinschaft']['PASSWORD'] %>
+ socket: /var/run/mysqld/mysqld.sock
+ reconnect: true
production:
adapter: mysql2
encoding: utf8
- database: gemeinschaft
+ database: <%= system_odbc_configuration['gemeinschaft']['DATABASE'] %>
pool: 10
- username: gemeinschaft
- password: gemeinschaft
+ username: <%= system_odbc_configuration['gemeinschaft']['USER'] %>
+ password: <%= system_odbc_configuration['gemeinschaft']['PASSWORD'] %>
socket: /var/run/mysqld/mysqld.sock
reconnect: true
+<% end %>
+<% end %>
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
diff --git a/config/environments/development.rb b/config/environments/development.rb
index bd34e4f..e677834 100644
--- a/config/environments/development.rb
+++ b/config/environments/development.rb
@@ -11,7 +11,10 @@ Gemeinschaft42c::Application.configure do
# Show full error reports and disable caching
config.consider_all_requests_local = true
+
+ # Enable caching for development
config.action_controller.perform_caching = false
+ CacheDigests::TemplateDigestor.cache = ActiveSupport::Cache::NullStore.new
# Don't care if the mailer can't send
config.action_mailer.raise_delivery_errors = false
@@ -37,7 +40,7 @@ Gemeinschaft42c::Application.configure do
# Enable Hirb:
extend Hirb::Console
- Hirb::View.enable
+ Hirb::View.enable
end
diff --git a/config/environments/production.rb b/config/environments/production.rb
index 4e5bdd8..344f8f8 100644
--- a/config/environments/production.rb
+++ b/config/environments/production.rb
@@ -30,14 +30,14 @@ Gemeinschaft42c::Application.configure do
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
- # See everything in the log (default is :info)
- # config.log_level = :debug
+ # Show only warnings in log files
+ config.log_level = :warn
# Use a different logger for distributed setups
# config.logger = SyslogLogger.new
# Use a different cache store in production
- # config.cache_store = :mem_cache_store
+ config.cache_store = :dalli_store
# Enable serving of images, stylesheets, and JavaScripts from an asset server
# config.action_controller.asset_host = "http://assets.example.com"
diff --git a/config/hirb.yml b/config/hirb.yml
index f011c9d..da7c083 100644
--- a/config/hirb.yml
+++ b/config/hirb.yml
@@ -198,4 +198,11 @@
- first_name
- user_name
- user
-
+ GatewaySetting:
+ :options:
+ :fields:
+ - id
+ - gateway
+ - name
+ - value
+ - class_type
diff --git a/config/initializers/gemeinschaft_parameters.rb b/config/initializers/gemeinschaft_parameters.rb
deleted file mode 100644
index b1481ef..0000000
--- a/config/initializers/gemeinschaft_parameters.rb
+++ /dev/null
@@ -1,81 +0,0 @@
-# Use this file to set generic parameters for Gemeinschaft
-
-GEMEINSCHAFT_VERSION = '5.0.2'
-SUPER_TENANT_NAME = 'Super-Tenant'
-
-# System defaults
-MINIMUM_PIN_LENGTH = 4
-MAXIMUM_PIN_LENGTH = 10
-
-# GUI
-GUI_REDIRECT_HTTPS = false
-
-# Phone numbers
-# Only touch this if you know what you are doing!
-STRICT_INTERNAL_EXTENSION_HANDLING = false
-STRICT_DID_HANDLING = false
-
-# SIP defaults
-DEFAULT_LENGTH_SIP_AUTH_NAME = 10
-DEFAULT_LENGTH_SIP_PASSWORD = 15
-CALL_WAITING = false
-DEFAULT_CLIR_SETTING = false
-DEFAULT_CLIP_SETTING = true
-
-TO_S_MAX_CALLER_NAME_LENGTH = 25
-TO_S_MAX_LENGTH_OF_AUTH_NAME = 6
-
-# Pagination defaults
-DEFAULT_PAGINATION_ENTRIES_PER_PAGE = 50
-
-# Conference defaults
-MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE = 100
-DEFAULT_MAX_CONFERENCE_MEMBERS = 10
-
-# Misc defaults
-MAX_EXTENSION_LENGTH = 6
-
-# Fax defaults
-DEFAULT_NUMBER_OF_RETRIES = 3
-DAYS_TILL_AUTO_DELETE = 90
-
-# Names of PhoneNumberRanges
-INTERNAL_EXTENSIONS = 'internal_extensions'
-SERVICE_NUMBERS = 'service_numbers'
-DIRECT_INWARD_DIALING_NUMBERS = 'direct_inward_dialing_numbers'
-
-# Callthrough defaults
-CALLTHROUGH_HAS_WHITELISTS = true
-
-# Hunt groups
-HUNT_GROUP_STRATEGIES = ['ring_all', 'ring_recursively']
-VALID_SECONDS_BETWEEN_JUMPS_VALUES = (1 .. 60).to_a.map{|x| x * 2}
-
-# Callforward
-DEFAULT_CALL_FORWARD_DEPTH = 1
-MAX_CALL_FORWARD_DEPTH = 40
-CALLFORWARD_DESTINATION_DEFAULT = '+49'
-CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT = true
-
-# Phone
-PROVISIONING_AUTO_ADD_PHONE = true
-PROVISIONING_AUTO_ADD_SIP_ACCOUNT = true
-PROVISIONING_AUTO_TENANT_ID = 2
-PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX = 'Gemeinschaft '
-PROVISIONING_IEEE8021X_EAP_USERNAME = ''
-PROVISIONING_IEEE8021X_EAP_PASSWORD = ''
-NIGHTLY_REBOOT_OF_PHONES = true
-SIEMENS_HISTORY_RELOAD_TIMES = {0..6 => 600, 7..20 => 40, 21..24 => 300}
-
-# API configuration
-DEFAULT_API_TENANT_ID = 2
-REMOTE_IP_ADDRESS_WHITELIST = [] # e.g. ['10.0.0.1']
-IMPORT_CSV_FILE = '/var/tmp/ExampleVoipCsvExport.csv'
-DOUBLE_CHECK_POSITIVE_USERS_CSV = '/var/tmp/ExampleDoubleCheckVoipCsvExport.csv'
-IMPORT_CSV_ENCODING = 'UTF-8'
-USER_NAME_PREFIX = 'dtc'
-CALLTHROUGH_NAME_TO_BE_USED_FOR_DEFAULT_ACTIVATION = 'Callthrough for employees'
-
-# GS Cluster configuration
-WRITE_GS_CLUSTER_SYNC_LOG = true
-HOMEBASE_IP_ADDRESS = '0.0.0.0'
diff --git a/config/initializers/secret_token.rb b/config/initializers/secret_token.rb
index 6f04f07..ecd511c 100644
--- a/config/initializers/secret_token.rb
+++ b/config/initializers/secret_token.rb
@@ -4,4 +4,4 @@
# If you change this key, all old signed cookies will become invalid!
# Make sure the secret is at least 30 characters and all random,
# no regular words or you'll be exposed to dictionary attacks.
-Gemeinschaft42c::Application.config.secret_token = '9a59cac7fe4b23e0253a7beb341d9498d721923e966b45983f441f991e81f758067a6d9a949247d489773288284ab96b5015be52bf7b2834e666d43f864034e4'
+Gemeinschaft42c::Application.config.secret_token = GsParameter.get('SECRET_TOKEN')
diff --git a/config/initializers/simple_form.rb b/config/initializers/simple_form.rb
index 2e3d9fb..ab84483 100644
--- a/config/initializers/simple_form.rb
+++ b/config/initializers/simple_form.rb
@@ -1,19 +1,176 @@
# Use this setup block to configure all options available in SimpleForm.
SimpleForm.setup do |config|
- config.wrappers :tag => :div, :class => :input,
- :error_class => :field_with_errors do |b|
+ # Wrappers are used by the form builder to generate a
+ # complete input. You can remove any component from the
+ # wrapper, change the order or even add your own to the
+ # stack. The options given below are used to wrap the
+ # whole input.
+ config.wrappers :default, :class => :input,
+ :hint_class => :field_with_hint, :error_class => :field_with_errors do |b|
+ ## Extensions enabled by default
+ # Any of these extensions can be disabled for a
+ # given input by passing: `f.input EXTENSION_NAME => false`.
+ # You can make any of these extensions optional by
+ # renaming `b.use` to `b.optional`.
- # Form extensions
+ # Determines whether to use HTML5 (:email, :url, ...)
+ # and required attributes
b.use :html5
- b.optional :pattern
- b.use :maxlength
+
+ # Calculates placeholders automatically from I18n
+ # You can also pass a string as f.input :placeholder => "Placeholder"
b.use :placeholder
- b.use :readonly
- # Form components
+ ## Optional extensions
+ # They are disabled unless you pass `f.input EXTENSION_NAME => :lookup`
+ # to the input. If so, they will retrieve the values from the model
+ # if any exists. If you want to enable the lookup for any of those
+ # extensions by default, you can change `b.optional` to `b.use`.
+
+ # Calculates maxlength from length validations for string inputs
+ b.optional :maxlength
+
+ # Calculates pattern from format validations for string inputs
+ b.optional :pattern
+
+ # Calculates min and max from length validations for numeric inputs
+ b.optional :min_max
+
+ # Calculates readonly automatically from readonly attributes
+ b.optional :readonly
+
+ ## Inputs
b.use :label_input
- b.use :error, :wrap_with => { :tag => :span, :class => :error }
b.use :hint, :wrap_with => { :tag => :span, :class => :hint }
+ b.use :error, :wrap_with => { :tag => :span, :class => :error }
+ end
+
+ config.wrappers :bootstrap, :tag => 'div', :class => 'control-group', :error_class => 'error' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.use :label
+ b.wrapper :tag => 'div', :class => 'controls' do |ba|
+ ba.use :input
+ ba.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
+ ba.use :hint, :wrap_with => { :tag => 'p', :class => 'help-block' }
+ end
+ end
+
+ config.wrappers :prepend, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.use :label
+ b.wrapper :tag => 'div', :class => 'controls' do |input|
+ input.wrapper :tag => 'div', :class => 'input-prepend' do |prepend|
+ prepend.use :input
+ end
+ input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
+ input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
+ end
end
+ config.wrappers :append, :tag => 'div', :class => "control-group", :error_class => 'error' do |b|
+ b.use :html5
+ b.use :placeholder
+ b.use :label
+ b.wrapper :tag => 'div', :class => 'controls' do |input|
+ input.wrapper :tag => 'div', :class => 'input-append' do |append|
+ append.use :input
+ end
+ input.use :hint, :wrap_with => { :tag => 'span', :class => 'help-block' }
+ input.use :error, :wrap_with => { :tag => 'span', :class => 'help-inline' }
+ end
+ end
+
+ # Wrappers for forms and inputs using the Twitter Bootstrap toolkit.
+ # Check the Bootstrap docs (http://twitter.github.com/bootstrap)
+ # to learn about the different styles for forms and inputs,
+ # buttons and other elements.
+ config.default_wrapper = :bootstrap
+
+ # Define the way to render check boxes / radio buttons with labels.
+ # Defaults to :nested for bootstrap config.
+ # :inline => input + label
+ # :nested => label > input
+ config.boolean_style = :nested
+
+ # Default class for buttons
+ config.button_class = 'btn'
+
+ # Method used to tidy up errors.
+ # config.error_method = :first
+
+ # Default tag used for error notification helper.
+ config.error_notification_tag = :div
+
+ # CSS class to add for error notification helper.
+ config.error_notification_class = 'alert alert-error'
+
+ # ID to add for error notification helper.
+ # config.error_notification_id = nil
+
+ # Series of attempts to detect a default label method for collection.
+ # config.collection_label_methods = [ :to_label, :name, :title, :to_s ]
+
+ # Series of attempts to detect a default value method for collection.
+ # config.collection_value_methods = [ :id, :to_s ]
+
+ # You can wrap a collection of radio/check boxes in a pre-defined tag, defaulting to none.
+ # config.collection_wrapper_tag = nil
+
+ # You can define the class to use on all collection wrappers. Defaulting to none.
+ # config.collection_wrapper_class = nil
+
+ # You can wrap each item in a collection of radio/check boxes with a tag,
+ # defaulting to :span. Please note that when using :boolean_style = :nested,
+ # SimpleForm will force this option to be a label.
+ # config.item_wrapper_tag = :span
+
+ # You can define a class to use in all item wrappers. Defaulting to none.
+ # config.item_wrapper_class = nil
+
+ # How the label text should be generated altogether with the required text.
+ # config.label_text = lambda { |label, required| "#{required} #{label}" }
+
+ # You can define the class to use on all labels. Default is nil.
+ config.label_class = 'control-label'
+
+ # You can define the class to use on all forms. Default is simple_form.
+ # config.form_class = :simple_form
+
+ # You can define which elements should obtain additional classes
+ # config.generate_additional_classes_for = [:wrapper, :label, :input]
+
+ # Whether attributes are required by default (or not). Default is true.
+ # config.required_by_default = true
+
+ # Tell browsers whether to use default HTML5 validations (novalidate option).
+ # Default is enabled.
+ config.browser_validations = false
+
+ # Collection of methods to detect if a file type was given.
+ # config.file_methods = [ :mounted_as, :file?, :public_filename ]
+
+ # Custom mappings for input types. This should be a hash containing a regexp
+ # to match as key, and the input type that will be used when the field name
+ # matches the regexp as value.
+ # config.input_mappings = { /count/ => :integer }
+
+ # Default priority for time_zone inputs.
+ # config.time_zone_priority = nil
+
+ # Default priority for country inputs.
+ # config.country_priority = nil
+
+ # Default size for text inputs.
+ # config.default_input_size = 50
+
+ # When false, do not use translations for labels.
+ # config.translate_labels = true
+
+ # Automatically discover new inputs in Rails' autoload path.
+ # config.inputs_discovery = true
+
+ # Cache SimpleForm inputs discovery
+ # config.cache_discovery = !Rails.env.development?
end
diff --git a/config/initializers/update_gs_version_number.rb b/config/initializers/update_gs_version_number.rb
new file mode 100644
index 0000000..d9e1aae
--- /dev/null
+++ b/config/initializers/update_gs_version_number.rb
@@ -0,0 +1,16 @@
+# The Gemeinschaft version is stored in an environment variable.
+# It equals the branch in git.
+#
+if !ENV['GS_VERSION'].nil? && GsParameter.table_exists? && GsParameter.get('GEMEINSCHAFT_VERSION') != ENV['GS_VERSION']
+ version = GsParameter.find_or_create_by_name('GEMEINSCHAFT_VERSION')
+ version.section = 'Generic'
+ version.value = ENV['GS_VERSION']
+ version.save
+end
+
+if !ENV['GS_BUILDNAME'].nil? && GsParameter.table_exists? && GsParameter.get('GS_BUILDNAME') != ENV['GS_BUILDNAME']
+ buildname = GsParameter.find_or_create_by_name('GEMEINSCHAFT_BUILDNAME')
+ buildname.section = 'Generic'
+ buildname.value = ENV['GS_BUILDNAME']
+ buildname.save
+end
diff --git a/config/locales/simple_form.en.yml b/config/locales/simple_form.en.yml
index 007d9f9..409e265 100644
--- a/config/locales/simple_form.en.yml
+++ b/config/locales/simple_form.en.yml
@@ -9,7 +9,7 @@ en:
# When using html, text and mark won't be used.
# html: '<abbr title="required">*</abbr>'
error_notification:
- default_message: "Some errors were found, please take a look."
+ default_message: "Some errors were found, please take a look:"
# Labels and hints examples
# labels:
# password: 'Password'
diff --git a/config/locales/views/call_routes/de.yml b/config/locales/views/call_routes/de.yml
new file mode 100644
index 0000000..71ad51a
--- /dev/null
+++ b/config/locales/views/call_routes/de.yml
@@ -0,0 +1,60 @@
+de:
+ call_routes:
+ name: 'Call Route'
+ controller:
+ successfuly_created: 'Call Route wurde angelegt.'
+ successfuly_updated: 'Call Route wurde aktualisiert.'
+ successfuly_destroyed: 'Call Route wurde gelöscht.'
+ index:
+ page_title: 'Liste aller Call Routen'
+ routing_table: 'Routing Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Call Route'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Call Route neu anlegen für %{resource}'
+ show:
+ page_title: 'Call Route bearbeiten'
+ routing_table: 'Routing Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Call Route neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Call Route bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ routing_table:
+ label: 'Routing Table'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ endpoint_type:
+ label: 'Endpoint type'
+ hint: ''
+ endpoint_id:
+ label: 'Endpoint'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/call_routes/en.yml b/config/locales/views/call_routes/en.yml
new file mode 100644
index 0000000..251f76e
--- /dev/null
+++ b/config/locales/views/call_routes/en.yml
@@ -0,0 +1,60 @@
+en:
+ call_routes:
+ name: 'Call route'
+ controller:
+ successfuly_created: 'Successfully created Call route.'
+ successfuly_updated: 'Successfully updated Call route.'
+ successfuly_destroyed: 'Successfully destroyed Call route.'
+ index:
+ page_title: 'Listing Call route'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this Call route?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Call route for %{resource}'
+ show:
+ page_title: 'Show Call route'
+ table: 'Table'
+ name: 'Name'
+ endpoint_type: 'Endpoint type'
+ endpoint_id: 'Endpoint'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Call route'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Call route'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ table:
+ label: 'Table'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ endpoint_type:
+ label: 'Endpoint type'
+ hint: ''
+ endpoint_id:
+ label: 'Endpoint'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/gateway_parameters/de.yml b/config/locales/views/gateway_parameters/de.yml
new file mode 100644
index 0000000..9c1cc3b
--- /dev/null
+++ b/config/locales/views/gateway_parameters/de.yml
@@ -0,0 +1,60 @@
+de:
+ gateway_parameters:
+ name: 'Gatewayparameter'
+ controller:
+ successfuly_created: 'Gatewayparameter wurde angelegt.'
+ successfuly_updated: 'Gatewayparameter wurde aktualisiert.'
+ successfuly_destroyed: 'Gatewayparameter wurde gelöscht.'
+ index:
+ page_title: 'Übersicht von Gatewayparameter'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Gatewayparameter'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Gatewayparameter neu anlegen für %{resource}'
+ show:
+ page_title: 'Gatewayparameter bearbeiten'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Gatewayparameter neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Gatewayparameter bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ gateway_id:
+ label: 'Gateway'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ value:
+ label: 'Value'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/gateway_parameters/en.yml b/config/locales/views/gateway_parameters/en.yml
new file mode 100644
index 0000000..8d84298
--- /dev/null
+++ b/config/locales/views/gateway_parameters/en.yml
@@ -0,0 +1,60 @@
+en:
+ gateway_parameters:
+ name: 'Gatewayparameter'
+ controller:
+ successfuly_created: 'Successfully created Gatewayparameter.'
+ successfuly_updated: 'Successfully updated Gatewayparameter.'
+ successfuly_destroyed: 'Successfully destroyed Gatewayparameter.'
+ index:
+ page_title: 'Listing Gatewayparameter'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this Gatewayparameter?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Gatewayparameter for %{resource}'
+ show:
+ page_title: 'Show Gatewayparameter'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Gatewayparameter'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Gatewayparameter'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ gateway_id:
+ label: 'Gateway'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ value:
+ label: 'Value'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/gateway_settings/de.yml b/config/locales/views/gateway_settings/de.yml
new file mode 100644
index 0000000..698a81a
--- /dev/null
+++ b/config/locales/views/gateway_settings/de.yml
@@ -0,0 +1,60 @@
+de:
+ gateway_settings:
+ name: 'Gateway Einstellungen'
+ controller:
+ successfuly_created: 'Gateway Einstellung wurde angelegt.'
+ successfuly_updated: 'Gateway Einstellung wurde aktualisiert.'
+ successfuly_destroyed: 'Gateway Einstellung wurde gelöscht.'
+ index:
+ page_title: 'Gateway Einstellungen'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Beschreibung'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Gateway Einstellungen'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Gateway Einstellungen neu anlegen für %{resource}'
+ show:
+ page_title: 'Gateway Einstellungen bearbeiten'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Beschreibung'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Gateway Einstellungen neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Gateway Einstellungen bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ gateway_id:
+ label: 'Gateway'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ value:
+ label: 'Value'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Beschreibung'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/gateway_settings/en.yml b/config/locales/views/gateway_settings/en.yml
new file mode 100644
index 0000000..63c1609
--- /dev/null
+++ b/config/locales/views/gateway_settings/en.yml
@@ -0,0 +1,60 @@
+en:
+ gateway_settings:
+ name: 'Gatewaysetting'
+ controller:
+ successfuly_created: 'Successfully created entry.'
+ successfuly_updated: 'Successfully updated entry.'
+ successfuly_destroyed: 'Successfully destroyed entry.'
+ index:
+ page_title: 'Gateway settings'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this entry?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New settings entry for %{resource}'
+ show:
+ page_title: 'Show Gatewaysetting'
+ gateway_id: 'Gateway'
+ name: 'Name'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Gateway settings entry'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Gateway settings'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ gateway_id:
+ label: 'Gateway'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ value:
+ label: 'Value'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/gateways/de.yml b/config/locales/views/gateways/de.yml
new file mode 100644
index 0000000..befe6b6
--- /dev/null
+++ b/config/locales/views/gateways/de.yml
@@ -0,0 +1,61 @@
+de:
+ gateways:
+ name: 'Gateway'
+ controller:
+ successfuly_created: 'Gateway wurde angelegt.'
+ successfuly_updated: 'Gateway wurde aktualisiert.'
+ successfuly_destroyed: 'Gateway wurde gelöscht.'
+ index:
+ page_title: 'Liste aller Gateways'
+ name: 'Name'
+ technology: 'Technologie'
+ inbound: 'Inbound'
+ outbound: 'Outbound'
+ description: 'Description'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Gateway'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Gateway neu anlegen für %{resource}'
+ show:
+ page_title: 'Gateway'
+ id: 'ID'
+ name: 'Name'
+ technology: 'Technologie'
+ inbound: 'Inbound'
+ outbound: 'Outbound'
+ description: 'Description'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Gateway neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Gateway bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ name:
+ label: 'Name'
+ hint: ''
+ technology:
+ label: 'Technologie'
+ hint: ''
+ inbound:
+ label: 'Inbound'
+ hint: ''
+ outbound:
+ label: 'Outbound'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/gateways/en.yml b/config/locales/views/gateways/en.yml
new file mode 100644
index 0000000..7732da1
--- /dev/null
+++ b/config/locales/views/gateways/en.yml
@@ -0,0 +1,61 @@
+en:
+ gateways:
+ name: 'Gateway'
+ controller:
+ successfuly_created: 'Successfully created Gateway.'
+ successfuly_updated: 'Successfully updated Gateway.'
+ successfuly_destroyed: 'Successfully destroyed Gateway.'
+ index:
+ page_title: 'Listing Gateway'
+ name: 'Name'
+ technology: 'Technology'
+ inbound: 'Inbound'
+ outbound: 'Outbound'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this Gateway?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Gateway for %{resource}'
+ show:
+ page_title: 'Gateway'
+ id: 'ID'
+ name: 'Name'
+ technology: 'Technology'
+ inbound: 'Inbound'
+ outbound: 'Outbound'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Gateway'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Gateway'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ name:
+ label: 'Name'
+ hint: ''
+ technology:
+ label: 'Technology'
+ hint: ''
+ inbound:
+ label: 'Inbound'
+ hint: ''
+ outbound:
+ label: 'Outbound'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/gemeinschaft_setups/de.yml b/config/locales/views/gemeinschaft_setups/de.yml
index a1dd989..d087583 100644
--- a/config/locales/views/gemeinschaft_setups/de.yml
+++ b/config/locales/views/gemeinschaft_setups/de.yml
@@ -25,4 +25,7 @@ de:
language_id:
label: 'Sprache'
hint: ''
+ default_area_code:
+ label: 'Standard Ortsvorwahl'
+ hint: '030 für Berlin, 0261 für Koblenz, 02631 für Neuwied, usw.'
button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/gemeinschaft_setups/en.yml b/config/locales/views/gemeinschaft_setups/en.yml
index aef2686..5e22e58 100644
--- a/config/locales/views/gemeinschaft_setups/en.yml
+++ b/config/locales/views/gemeinschaft_setups/en.yml
@@ -25,4 +25,7 @@ en:
language_id:
label: 'Language'
hint: ''
+ default_area_code:
+ label: 'Default area code'
+ hint: ''
button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/gs_parameters/de.yml b/config/locales/views/gs_parameters/de.yml
new file mode 100644
index 0000000..9e22eb0
--- /dev/null
+++ b/config/locales/views/gs_parameters/de.yml
@@ -0,0 +1,63 @@
+de:
+ gs_parameters:
+ name: 'Gemeinschaft Parameter'
+ controller:
+ successfuly_created: 'Ein Gemeinschaft Parameter wurde angelegt.'
+ successfuly_updated: 'Ein Gemeinschaft Parameter wurde aktualisiert. Bitte rebooten Sie Ihr System jetzt!'
+ successfuly_destroyed: 'Ein Gemeinschaft Parameter wurde gelöscht.'
+ index:
+ page_title: 'Übersicht aller Gemeinschaft Parameter'
+ name: 'Name'
+ section: 'Section'
+ value: 'Wert'
+ class_type: 'Class type'
+ description: 'Beschreibung'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Gemeinschaft Parameter'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Gemeinschaft Parameter neu anlegen für %{resource}'
+ show:
+ page_title: 'Gemeinschaft Parameter anzeigen'
+ name: 'Name'
+ section: 'Section'
+ value: 'Wert'
+ class_type: 'Class type'
+ description: 'Beschreibung'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Gemeinschaft Parameter neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Gemeinschaft Parameter bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ entity:
+ label: 'Instanz'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ section:
+ label: 'Section'
+ hint: ''
+ value:
+ label: 'Wert'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Beschreibung'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/gs_parameters/en.yml b/config/locales/views/gs_parameters/en.yml
new file mode 100644
index 0000000..9dbdcb2
--- /dev/null
+++ b/config/locales/views/gs_parameters/en.yml
@@ -0,0 +1,64 @@
+en:
+ gs_parameters:
+ name: 'Gemeinschaft parameter'
+ controller:
+ successfuly_created: 'Successfully created a Gemeinschaft parameter.'
+ successfuly_updated: 'Successfully updated a Gemeinschaft parameter. Please reboot your system now!'
+ successfuly_destroyed: 'Successfully destroyed a Gemeinschaft parameter.'
+ index:
+ page_title: 'Listing Gemeinschaft parameter'
+ name: 'Name'
+ section: 'Section'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this Gemeinschaft parameter?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Gemeinschaft parameter for %{resource}'
+ show:
+ page_title: 'Show Gemeinschaft parameter'
+ name: 'Name'
+ section: 'Section'
+ value: 'Value'
+ class_type: 'Class type'
+ description: 'Description'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ reboot_warning: 'Nach der Änderung eines Gemeinschaft Parameters müssen Sie das System neu booten!'
+ new:
+ page_title: 'New Gemeinschaft parameter'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Gemeinschaft parameter'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ entity:
+ label: 'Entity'
+ hint: ''
+ name:
+ label: 'Name'
+ hint: ''
+ section:
+ label: 'Section'
+ hint: ''
+ value:
+ label: 'Value'
+ hint: ''
+ class_type:
+ label: 'Class type'
+ hint: ''
+ description:
+ label: 'Description'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/phone_numbers/de.yml b/config/locales/views/phone_numbers/de.yml
index 40fc7f8..e801ab4 100644
--- a/config/locales/views/phone_numbers/de.yml
+++ b/config/locales/views/phone_numbers/de.yml
@@ -34,7 +34,8 @@ de:
confirm: 'Sind Sie sicher, dass Sie diese Telefonnummer löschen möchten?'
destroy: 'Löschen'
edit: 'Bearbeiten'
- view_all: 'View all phone numbers'
+ view_all: 'Alle anzeigen'
+ call: 'Anrufen'
new:
page_title: 'Neue Telefonnummer'
edit:
diff --git a/config/locales/views/phone_numbers/en.yml b/config/locales/views/phone_numbers/en.yml
index 31af5c8..be3b4f5 100644
--- a/config/locales/views/phone_numbers/en.yml
+++ b/config/locales/views/phone_numbers/en.yml
@@ -35,6 +35,7 @@ en:
destroy: 'Delete'
edit: 'Edit'
view_all: 'View all phone numbers'
+ call: 'Call'
new:
page_title: 'New Phone number'
edit:
diff --git a/config/locales/views/route_elements/de.yml b/config/locales/views/route_elements/de.yml
new file mode 100644
index 0000000..d2c6c39
--- /dev/null
+++ b/config/locales/views/route_elements/de.yml
@@ -0,0 +1,75 @@
+de:
+ route_elements:
+ name: 'Route element'
+ controller:
+ successfuly_created: 'Route element wurde angelegt.'
+ successfuly_updated: 'Route element wurde aktualisiert.'
+ successfuly_destroyed: 'Route element wurde gelöscht.'
+ index:
+ page_title: 'Übersicht von Route element'
+ call_route_id: 'Call route'
+ var_in: 'Var in'
+ var_out: 'Var out'
+ pattern: 'Pattern'
+ replacement: 'Replacement'
+ action: 'Action'
+ mandatory: 'Mandatory'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass Sie folgendes löschen möchten: Route element'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ show: 'Anzeigen'
+ create: 'Neu anlegen'
+ create_for: 'Route element neu anlegen für %{resource}'
+ show:
+ page_title: 'Route element bearbeiten'
+ call_route_id: 'Call route'
+ var_in: 'Var in'
+ var_out: 'Var out'
+ pattern: 'Pattern'
+ replacement: 'Replacement'
+ action: 'Action'
+ mandatory: 'Mandatory'
+ position: 'Position'
+ actions:
+ confirm: 'Sind Sie sicher, dass die dieses Element löschen möchten?'
+ destroy: 'Löschen'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ new:
+ page_title: 'Route element neu anlegen'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit:
+ page_title: 'Route element bearbeiten'
+ actions:
+ back_to_list: 'Zurück zur Übersicht'
+ edit: 'Bearbeiten'
+ view_all: 'Alle anzeigen'
+ form:
+ call_route_id:
+ label: 'Call route'
+ hint: ''
+ var_in:
+ label: 'Var in'
+ hint: ''
+ var_out:
+ label: 'Var out'
+ hint: ''
+ pattern:
+ label: 'Pattern'
+ hint: ''
+ replacement:
+ label: 'Replacement'
+ hint: ''
+ action:
+ label: 'Action'
+ hint: ''
+ mandatory:
+ label: 'Mandatory'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Absenden' \ No newline at end of file
diff --git a/config/locales/views/route_elements/en.yml b/config/locales/views/route_elements/en.yml
new file mode 100644
index 0000000..1340309
--- /dev/null
+++ b/config/locales/views/route_elements/en.yml
@@ -0,0 +1,75 @@
+en:
+ route_elements:
+ name: 'Route element'
+ controller:
+ successfuly_created: 'Successfully created Route element.'
+ successfuly_updated: 'Successfully updated Route element.'
+ successfuly_destroyed: 'Successfully destroyed Route element.'
+ index:
+ page_title: 'Listing Route element'
+ call_route_id: 'Call route'
+ var_in: 'Var in'
+ var_out: 'Var out'
+ pattern: 'Pattern'
+ replacement: 'Replacement'
+ action: 'Action'
+ mandatory: 'Mandatory'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this Route element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ show: 'View'
+ create: 'New'
+ create_for: 'New Route element for %{resource}'
+ show:
+ page_title: 'Show Route element'
+ call_route_id: 'Call route'
+ var_in: 'Var in'
+ var_out: 'Var out'
+ pattern: 'Pattern'
+ replacement: 'Replacement'
+ action: 'Action'
+ mandatory: 'Mandatory'
+ position: 'Position'
+ actions:
+ confirm: 'Are you sure you want to delete this element?'
+ destroy: 'Delete'
+ edit: 'Edit'
+ view_all: 'View All'
+ new:
+ page_title: 'New Route element'
+ actions:
+ back_to_list: 'Back to Index'
+ edit:
+ page_title: 'Editing Route element'
+ actions:
+ back_to_list: 'Back to Index'
+ edit: 'Edit'
+ view_all: 'View All'
+ form:
+ call_route_id:
+ label: 'Call route'
+ hint: ''
+ var_in:
+ label: 'Var in'
+ hint: ''
+ var_out:
+ label: 'Var out'
+ hint: ''
+ pattern:
+ label: 'Pattern'
+ hint: ''
+ replacement:
+ label: 'Replacement'
+ hint: ''
+ action:
+ label: 'Action'
+ hint: ''
+ mandatory:
+ label: 'Mandatory'
+ hint: ''
+ position:
+ label: 'Position'
+ hint: ''
+ button: 'Submit' \ No newline at end of file
diff --git a/config/locales/views/users/de.yml b/config/locales/views/users/de.yml
index 951600d..e4a0ae2 100644
--- a/config/locales/views/users/de.yml
+++ b/config/locales/views/users/de.yml
@@ -1,15 +1,15 @@
de:
users:
- name: "Benutzer"
+ name: "User"
controller:
- successfuly_created: 'Der Benutzer %{resource} wurde erstellt.'
- successfuly_created_and_login: 'Der Benutzer %{resource} wurde erstellt. Sie sind jetzt als dieser Benutzer angemeldet.'
- successfuly_updated: 'Benutzer-Daten aktualisiert.'
- successfuly_destroyed: 'Der Benutzer wurde gelöscht.'
+ successfuly_created: 'Der User %{resource} wurde erstellt.'
+ successfuly_created_and_login: 'Der User %{resource} wurde erstellt. Sie sind jetzt als dieser User angemeldet.'
+ successfuly_updated: 'User-Daten aktualisiert.'
+ successfuly_destroyed: 'Der User wurde gelöscht.'
avatar_destroyed: 'Der Avatar wurde gelöscht.'
index:
- page_title: 'Benutzer'
- user_name: 'Benutzer-Name'
+ page_title: 'User'
+ user_name: 'User-Name'
email: 'E-Mail Adresse'
first_name: 'Vorname'
middle_name: 'Zweiter Vorname'
@@ -20,15 +20,15 @@ de:
language_id: 'Sprache'
send_voicemail_as_email_attachment: 'Sprachnachrichten per E-Mail'
actions:
- confirm: 'Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?'
+ confirm: 'Sind Sie sicher, dass Sie diesen User löschen möchten?'
destroy: 'Löschen'
edit: 'Bearbeiten'
show: 'Anzeigen'
- create: 'Neuen Benutzer anlegen'
- create_for: 'Neuen Benutzer für %{resource} anlegen'
+ create: 'Neuen User anlegen'
+ create_for: 'Neuen User für %{resource} anlegen'
show:
- page_title: 'Benutzer anzeigen'
- user_name: 'Benutzer-Name'
+ page_title: 'User anzeigen'
+ user_name: 'User-Name'
email: 'E-Mail Adresse'
first_name: 'Vorname'
middle_name: 'Zweiter Vorname'
@@ -39,17 +39,17 @@ de:
language_id: 'Sprache'
send_voicemail_as_email_attachment: 'Sprachnachrichten per E-Mail'
actions:
- confirm: 'Sind Sie sicher, dass Sie diesen Benutzer löschen möchten?'
+ confirm: 'Sind Sie sicher, dass Sie diesen User löschen möchten?'
destroy: 'Löschen'
edit: 'Bearbeiten'
- view_all: 'Alle Benutzer anzeigen'
+ view_all: 'Alle User anzeigen'
new:
- page_title: 'Neuen Benutzer anlegen'
+ page_title: 'Neuen User anlegen'
edit:
- page_title: 'Benutzer %{resource} bearbeiten'
+ page_title: 'User %{resource} bearbeiten'
form:
user_name:
- label: 'Benutzer-Name'
+ label: 'User-Name'
hint: ''
email:
label: 'E-Mail Adresse'
diff --git a/config/routes.rb b/config/routes.rb
index 33238dc..22a36e5 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -1,4 +1,30 @@
Gemeinschaft42c::Application.routes.draw do
+
+ scope :constraints => lambda{|req|%w(127.0.0.1).include? req.remote_addr} do
+ get "trigger/voicemail"
+ get "trigger/fax"
+ end
+
+ resources :call_routes do
+ resources :route_elements do
+ member do
+ put 'move_higher'
+ put 'move_lower'
+ end
+ end
+ member do
+ put 'move_higher'
+ put 'move_lower'
+ end
+ end
+
+ resources :gateways do
+ resources :gateway_settings
+ resources :gateway_parameters
+ end
+
+ resources :gs_parameters, :only => [:show, :index, :update, :edit]
+
resources :automatic_call_distributors
resources :gs_cluster_sync_log_entries
@@ -53,7 +79,7 @@ Gemeinschaft42c::Application.routes.draw do
end
end
- if CALLTHROUGH_HAS_WHITELISTS == true
+ if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
resources :whitelists, :only => [] do
resources :phone_numbers do
member do
@@ -237,7 +263,7 @@ Gemeinschaft42c::Application.routes.draw do
resources :conferences
resources :phone_number_ranges
resources :callthroughs
- if CALLTHROUGH_HAS_WHITELISTS == true
+ if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
resources :whitelists
end
resources :hunt_groups
@@ -252,7 +278,7 @@ Gemeinschaft42c::Application.routes.draw do
put 'move_lower'
end
end
- if CALLTHROUGH_HAS_WHITELISTS == true
+ if GsParameter.get('CALLTHROUGH_HAS_WHITELISTS') == true
resources :whitelists
end
end
@@ -302,6 +328,7 @@ Gemeinschaft42c::Application.routes.draw do
member do
put 'move_higher'
put 'move_lower'
+ put 'call'
end
end
end
diff --git a/config/unicorn.rb b/config/unicorn.rb
new file mode 100644
index 0000000..8157562
--- /dev/null
+++ b/config/unicorn.rb
@@ -0,0 +1,34 @@
+APP_ROOT = File.expand_path(File.dirname(File.dirname(__FILE__)))
+
+worker_processes 1
+working_directory APP_ROOT
+
+preload_app true
+
+timeout 30
+
+listen APP_ROOT + "/tmp/sockets/unicorn.sock", :backlog => 64
+
+pid APP_ROOT + "/tmp/pids/unicorn.pid"
+
+stderr_path APP_ROOT + "/log/unicorn.stderr.log"
+stdout_path APP_ROOT + "/log/unicorn.stdout.log"
+
+before_fork do |server, worker|
+ defined?(ActiveRecord::Base) && ActiveRecord::Base.connection.disconnect!
+
+ old_pid = Rails.root + '/tmp/pids/unicorn.pid.oldbin'
+ if File.exists?(old_pid) && server.pid != old_pid
+ begin
+ Process.kill("QUIT", File.read(old_pid).to_i)
+ rescue Errno::ENOENT, Errno::ESRCH
+ puts "Old master alerady dead"
+ end
+ end
+end
+
+after_fork do |server, worker|
+ defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection
+ child_pid = server.config[:pid].sub('.pid', ".#{worker.nr}.pid")
+ system("echo #{Process.pid} > #{child_pid}")
+end
diff --git a/db/migrate/20121230110747_snom_meetingpoint.rb b/db/migrate/20121230110747_snom_meetingpoint.rb
index 04ad450..0042979 100644
--- a/db/migrate/20121230110747_snom_meetingpoint.rb
+++ b/db/migrate/20121230110747_snom_meetingpoint.rb
@@ -2,7 +2,7 @@ class SnomMeetingpoint < ActiveRecord::Migration
def up
if Manufacturer.where(:ieee_name => 'SNOM Technology AG').any?
snom = Manufacturer.where(:ieee_name => 'SNOM Technology AG').first
- snom.phone_models.create(:name => 'snom MeetingPoint',
+ snom.phone_models.create(:name => 'Snom meetingPoint',
:product_homepage_url => 'http://www.snom.com/en/products/sip-conference-phone/snom-meetingpoint/',
:product_manual_homepage_url => 'http://wiki.snom.com/Snom_MeetingPoint/Documentation')
end
diff --git a/db/migrate/20130105120126_create_gs_parameters.rb b/db/migrate/20130105120126_create_gs_parameters.rb
new file mode 100644
index 0000000..b8b915b
--- /dev/null
+++ b/db/migrate/20130105120126_create_gs_parameters.rb
@@ -0,0 +1,16 @@
+class CreateGsParameters < ActiveRecord::Migration
+ def self.up
+ create_table :gs_parameters do |t|
+ t.string :name
+ t.string :section
+ t.text :value
+ t.string :class_type
+ t.string :description
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :gs_parameters
+ end
+end
diff --git a/db/migrate/20130105120353_populate_gs_parameter_with_defaults.rb b/db/migrate/20130105120353_populate_gs_parameter_with_defaults.rb
new file mode 100644
index 0000000..a84e939
--- /dev/null
+++ b/db/migrate/20130105120353_populate_gs_parameter_with_defaults.rb
@@ -0,0 +1,104 @@
+class PopulateGsParameterWithDefaults < ActiveRecord::Migration
+ def up
+ add_column :gs_parameters, :entity, :string, :after => :id
+ # Generic
+ #
+ GsParameter.create(:name => 'GEMEINSCHAFT_VERSION', :section => 'Generic', :value => '5.0.2-nightly-build', :class_type => 'String')
+ GsParameter.create(:name => 'SUPER_TENANT_NAME', :section => 'Generic', :value => 'Super-Tenant', :class_type => 'String')
+
+ # System defaults
+ #
+ GsParameter.create(:name => 'MINIMUM_PIN_LENGTH', :section => 'System defaults', :value => '4', :class_type => 'Integer')
+ GsParameter.create(:name => 'MAXIMUM_PIN_LENGTH', :section => 'System defaults', :value => '10', :class_type => 'Integer')
+
+ # GUI
+ #
+ GsParameter.create(:name => 'GUI_REDIRECT_HTTPS', :section => 'GUI', :value => 'false', :class_type => 'Boolean')
+
+ # Phone numbers
+ # Only touch this if you know what you are doing!
+ #
+ GsParameter.create(:name => 'STRICT_INTERNAL_EXTENSION_HANDLING', :section => 'Phone numbers', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:name => 'STRICT_DID_HANDLING', :section => 'Phone numbers', :value => 'false', :class_type => 'Boolean')
+
+ # SIP defaults
+ #
+ GsParameter.create(:name => 'DEFAULT_LENGTH_SIP_AUTH_NAME', :section => 'SIP Defaults', :value => '10', :class_type => 'Integer')
+ GsParameter.create(:name => 'DEFAULT_LENGTH_SIP_PASSWORD', :section => 'SIP Defaults', :value => '15', :class_type => 'Integer')
+ GsParameter.create(:name => 'CALL_WAITING', :section => 'SIP Defaults', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:name => 'DEFAULT_CLIR_SETTING', :section => 'SIP Defaults', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:name => 'DEFAULT_CLIP_SETTING', :section => 'SIP Defaults', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:name => 'TO_S_MAX_CALLER_NAME_LENGTH', :section => 'SIP Defaults', :value => '25', :class_type => 'Integer')
+ GsParameter.create(:name => 'TO_S_MAX_LENGTH_OF_AUTH_NAME', :section => 'SIP Defaults', :value => '6', :class_type => 'Integer')
+
+ # Pagination defaults
+ #
+ GsParameter.create(:name => 'DEFAULT_PAGINATION_ENTRIES_PER_PAGE', :section => 'Pagination defaults', :value => '50', :class_type => 'Integer')
+
+ # Conference defaults
+ #
+ GsParameter.create(:name => 'MAXIMUM_NUMBER_OF_PEOPLE_IN_A_CONFERENCE', :section => 'Conference defaults', :value => '100', :class_type => 'Integer')
+ GsParameter.create(:name => 'DEFAULT_MAX_CONFERENCE_MEMBERS', :section => 'Conference defaults', :value => '10', :class_type => 'Integer')
+
+ # Misc defaults
+ #
+ GsParameter.create(:name => 'MAX_EXTENSION_LENGTH', :section => 'Misc defaults', :value => '6', :class_type => 'Integer')
+
+ # Fax defaults
+ #
+ GsParameter.create(:name => 'DEFAULT_NUMBER_OF_RETRIES', :section => 'Fax defaults', :value => '3', :class_type => 'Integer')
+ GsParameter.create(:name => 'DAYS_TILL_AUTO_DELETE', :section => 'Fax defaults', :value => '90', :class_type => 'Integer')
+
+ # Names of PhoneNumberRanges
+ #
+ GsParameter.create(:name => 'INTERNAL_EXTENSIONS', :section => 'PhoneNumberRanges defaults', :value => 'internal_extensions', :class_type => 'String')
+ GsParameter.create(:name => 'SERVICE_NUMBERS', :section => 'PhoneNumberRanges defaults', :value => 'service_numbers', :class_type => 'String')
+ GsParameter.create(:name => 'DIRECT_INWARD_DIALING_NUMBERS', :section => 'PhoneNumberRanges defaults', :value => 'direct_inward_dialing_numbers', :class_type => 'String')
+
+ # Callthrough defaults
+ #
+ GsParameter.create(:name => 'CALLTHROUGH_HAS_WHITELISTS', :section => 'Callthrough defaults', :value => 'true', :class_type => 'Boolean')
+
+ # Huntgroup defaults
+ #
+ GsParameter.create(:name => 'HUNT_GROUP_STRATEGIES', :section => 'Huntgroup defaults', :value => ['ring_all', 'ring_recursively'].to_yaml, :class_type => 'YAML')
+ GsParameter.create(:name => 'VALID_SECONDS_BETWEEN_JUMPS_VALUES', :section => 'Huntgroup defaults', :value => (1 .. 60).to_a.map{|x| x * 2}.to_yaml, :class_type => 'YAML')
+
+ # Callforward defaults
+ #
+ GsParameter.create(:name => 'DEFAULT_CALL_FORWARD_DEPTH', :section => 'Callforward defaults', :value => '1', :class_type => 'Integer')
+ GsParameter.create(:name => 'MAX_CALL_FORWARD_DEPTH', :section => 'Callforward defaults', :value => '40', :class_type => 'Integer')
+ GsParameter.create(:name => 'CALLFORWARD_DESTINATION_DEFAULT', :section => 'Callforward defaults', :value => '+49', :class_type => 'String')
+ GsParameter.create(:name => 'CALLFORWARD_RULES_ACT_PER_SIP_ACCOUNT_DEFAULT', :section => 'Callforward defaults', :value => 'true', :class_type => 'Boolean')
+
+ # Phone
+ #
+ GsParameter.create(:name => 'PROVISIONING_AUTO_ADD_PHONE', :section => 'Phone', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:name => 'PROVISIONING_AUTO_ADD_SIP_ACCOUNT', :section => 'Phone', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:name => 'PROVISIONING_AUTO_TENANT_ID', :section => 'Phone', :value => '2', :class_type => 'Integer')
+ GsParameter.create(:name => 'PROVISIONING_AUTO_SIP_ACCOUNT_CALLER_PREFIX', :section => 'Phone', :value => 'Gemeinschaft ', :class_type => 'String')
+ GsParameter.create(:name => 'PROVISIONING_IEEE8021X_EAP_USERNAME', :section => 'Phone', :value => '', :class_type => 'String')
+ GsParameter.create(:name => 'PROVISIONING_IEEE8021X_EAP_PASSWORD', :section => 'Phone', :value => '', :class_type => 'String')
+ GsParameter.create(:name => 'NIGHTLY_REBOOT_OF_PHONES', :section => 'Phone', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:name => 'SIEMENS_HISTORY_RELOAD_TIMES', :section => 'Phone', :value => {0..6 => 600, 7..20 => 40, 21..24 => 300}.to_yaml, :class_type => 'YAML')
+
+ # API configuration
+ #
+ GsParameter.create(:name => 'DEFAULT_API_TENANT_ID', :section => 'API configuration', :value => '2', :class_type => 'Integer')
+ GsParameter.create(:name => 'REMOTE_IP_ADDRESS_WHITELIST', :section => 'API configuration', :value => [].to_yaml, :class_type => 'YAML') # e.g. ['10.0.0.1']
+ GsParameter.create(:name => 'IMPORT_CSV_FILE', :section => 'API configuration', :value => '/var/tmp/ExampleVoipCsvExport.csv', :class_type => 'String')
+ GsParameter.create(:name => 'DOUBLE_CHECK_POSITIVE_USERS_CSV', :section => 'API configuration', :value => '/var/tmp/ExampleDoubleCheckVoipCsvExport.csv', :class_type => 'String')
+ GsParameter.create(:name => 'IMPORT_CSV_ENCODING', :section => 'API configuration', :value => 'UTF-8', :class_type => 'String')
+ GsParameter.create(:name => 'USER_NAME_PREFIX', :section => 'API configuration', :value => 'dtc', :class_type => 'String')
+ GsParameter.create(:name => 'CALLTHROUGH_NAME_TO_BE_USED_FOR_DEFAULT_ACTIVATION', :section => 'API configuration', :value => 'Callthrough for employees', :class_type => 'String')
+
+ # GS Cluster configuration
+ #
+ GsParameter.create(:name => 'WRITE_GS_CLUSTER_SYNC_LOG', :section => 'GS Cluster ', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:name => 'HOMEBASE_IP_ADDRESS', :section => 'GS Cluster ', :value => '0.0.0.0', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.destroy_all
+ end
+end
diff --git a/db/migrate/20130107222128_set_provisioning_set_http_user.rb b/db/migrate/20130107222128_set_provisioning_set_http_user.rb
new file mode 100644
index 0000000..8066fb9
--- /dev/null
+++ b/db/migrate/20130107222128_set_provisioning_set_http_user.rb
@@ -0,0 +1,13 @@
+class SetProvisioningSetHttpUser < ActiveRecord::Migration
+ def up
+ # Provisioning stuff
+ #
+ GsParameter.create(:name => 'PROVISIONING_SET_HTTP_USER', :section => 'Provisioning', :value => 'admin', :class_type => 'String')
+ GsParameter.create(:name => 'PROVISIONING_SET_HTTP_PASSWORD', :section => 'Provisioning', :value => '8', :class_type => 'Integer')
+ end
+
+ def down
+ GsParameter.where(:name => 'PROVISIONING_SET_HTTP_USER').destroy_all
+ GsParameter.where(:name => 'PROVISIONING_SET_HTTP_PASSWORD').destroy_all
+ end
+end
diff --git a/db/migrate/20130109074326_add_entity_to_gs_parameter.rb b/db/migrate/20130109074326_add_entity_to_gs_parameter.rb
new file mode 100644
index 0000000..b1c0d4b
--- /dev/null
+++ b/db/migrate/20130109074326_add_entity_to_gs_parameter.rb
@@ -0,0 +1,6 @@
+class AddEntityToGsParameter < ActiveRecord::Migration
+ def change
+ add_column :gs_parameters, :entity, :string, :after => :id rescue puts "column already added"
+
+ end
+end
diff --git a/db/migrate/20130109090000_populate_gs_parameter_with_dialplan_defaults.rb b/db/migrate/20130109090000_populate_gs_parameter_with_dialplan_defaults.rb
new file mode 100644
index 0000000..fe1cdae
--- /dev/null
+++ b/db/migrate/20130109090000_populate_gs_parameter_with_dialplan_defaults.rb
@@ -0,0 +1,121 @@
+class PopulateGsParameterWithDialplanDefaults < ActiveRecord::Migration
+ def up
+ # sip account defaults
+ GsParameter.create(:entity => 'sip_accounts', :section => 'parameters', :name => 'vm-enabled', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sip_accounts', :section => 'parameters', :name => 'vm-email-all-messages', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sip_accounts', :section => 'parameters', :name => 'vm-attach-file', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sip_accounts', :section => 'parameters', :name => 'vm-mailto', :value => '', :class_type => 'String')
+ GsParameter.create(:entity => 'sip_accounts', :section => 'parameters', :name => 'sip-force-contact', :value => '', :class_type => 'String')
+
+ #sofia defaults
+ GsParameter.create(:entity => 'sofia', :section => 'profiles', :name => 'gemeinschaft', :value => 1, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'parameters', :name => 'log-level', :value => 3, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'parameters', :name => 'debug-presence', :value => 0, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'user-agent-string', :value => 'Gemeinschaft5', :class_type => 'String')
+
+ # default profile
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'debug', :value => 0, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'sip-trace', :value => 'no', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'log-auth-failures', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'context', :value => 'default', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'rfc2833-pt', :value => 101, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'pass-rfc2833', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'sip-port', :value => 5060, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'dialplan', :value => 'XML', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'dtmf-duration', :value => 2000, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'rtp-timer-name', :value => 'soft', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'inbound-codec-prefs', :value => 'PCMA,G7221@32000h,G7221@16000h,G722,PCMU,GSM', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'outbound-codec-prefs', :value => 'PCMA,G7221@32000h,G7221@16000h,G722,PCMU,GSM', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'inbound-codec-negotiation', :value => 'greedy', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'ext-rtp-ip', :value => 'auto-nat', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'ext-sip-ip', :value => 'auto-nat', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'hold-music', :value => 'local_stream://moh', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'manage-presence', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'tls', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'tls-sip-port', :value => 5061, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'tls-cert-dir', :value => '/opt/freeswitch/conf/ssl', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'accept-blind-reg', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'accept-blind-auth', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'nonce-ttl', :value => 60, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'disable-transcoding', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'manual-redirect', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'disable-transfer', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'disable-register', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'auth-calls', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'inbound-reg-force-matching-username', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'auth-all-packets', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'rtp-timeout-sec', :value => 300, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'rtp-hold-timeout-sec', :value => 1800, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'force-subscription-expires', :value => 3600, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'sip-force-expires', :value => 3000, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'sip-expires-max-deviation', :value => 600, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'challenge-realm', :value => 'auto_from', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'rtp-rewrite-timestamps', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'inbound-use-callid-as-uuid', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'outbound-use-callid-as-uuid', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'context', :value => 'default', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'record-template', :value => '${user_name}_${uuid}_${strftime(%Y-%m-%d-%H-%M-%S)}.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'all-reg-options-ping', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'mark-dead-on-options-fail', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'registration-thread-frequency', :value => 300, :class_type => 'Integer')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'NDLB-force-rport', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'odbc-dsn', :value => 'gemeinschaft:gemeinschaft:gemeinschaft', :class_type => 'String')
+
+ # event manager defaults
+ GsParameter.create(:entity => 'events', :section => 'modules', :name => 'cdr_save', :value => 1, :class_type => 'Integer')
+ GsParameter.create(:entity => 'events', :section => 'modules', :name => 'call_history_save', :value => 2, :class_type => 'Integer')
+ GsParameter.create(:entity => 'events', :section => 'modules', :name => 'presence_update', :value => 3, :class_type => 'Integer')
+
+ # perimeter defaults
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_count', :value => 20, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'malicious_contact_time_span', :value => 2, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'ban_futile', :value => 5, :class_type => 'Integer')
+ GsParameter.create(:entity => 'perimeter', :section => 'general', :name => 'execute', :value => 'sudo /usr/local/bin/ban_ip.sh {ip_address}', :class_type => 'String')
+
+ # conferences defaults
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'caller-controls', :value => 'speaker', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'moderator-controls', :value => 'moderator', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'max-members', :value => 100, :class_type => 'Integer')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'rate', :value => 16000, :class_type => 'Integer')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'interval', :value => 20, :class_type => 'Integer')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'energy-level', :value => 300, :class_type => 'Integer')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'sound-prefix', :value => '/opt/freeswitch/sounds/en/us/callie', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'muted-sound', :value => 'conference/conf-muted.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'unmuted-sound', :value => 'conference/conf-unmuted.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'alone-sound', :value => 'conference/conf-alone.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'moh-sound', :value => 'local_stream://moh', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'enter-sound', :value => 'tone_stream://%(200,0,500,600,700)', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'exit-sound', :value => 'tone_stream://%(500,0,300,200,100,50,25)', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'kicked-sound', :value => 'conference/conf-kicked.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'locked-sound', :value => 'conference/conf-locked.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'is-locked-sound', :value => 'conference/conf-is-locked.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'is-unlocked-sound', :value => 'conference/conf-is-unlocked.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'pin-sound', :value => 'conference/conf-pin.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'bad-pin-sound', :value => 'conference/conf-bad-pin.wav', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'caller-id-name', :value => 'Conference', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'caller-id-number', :value => '', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'parameters', :name => 'comfort-noise', :value => 'true', :class_type => 'Boolean')
+
+ #dialplan defaults
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'node_id', :value => 1, :class_type => 'Integer')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'dial_timeout', :value => '120', :class_type => 'Integer')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'max_loops', :value => '20', :class_type => 'Integer')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'default_ringtone', :value => '1', :class_type => 'Integer')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'default_language', :value => 'en', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'phone_book_entry_image_url', :value => 'http://192.168.0.150/uploads/phone_book_entry/image', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'user_image_url', :value => 'http://192.168.0.150/uploads/user/image', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'ringtone_url', :value => 'http://192.168.0.150', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'ringback', :value => '%(2000,4000,440.0,480.0)', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'tone_busy', :value => '%(500,500,480,620);loops=4', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'phonebook_number_lookup', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'geo_number_lookup', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'send_ringing_to_gateways', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'bypass_media_network', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'update_callee_display', :value => 'false', :class_type => 'Boolean')
+ end
+
+ def down
+ entities = ['sip_accounts', 'sofia', 'events', 'perimeter', 'conferences', 'dialplan']
+ GsParameter.where(:entity => entities).destroy_all
+ end
+end
diff --git a/db/migrate/20130109182800_change_gs_parameter_odbc_defaults.rb b/db/migrate/20130109182800_change_gs_parameter_odbc_defaults.rb
new file mode 100644
index 0000000..1958c44
--- /dev/null
+++ b/db/migrate/20130109182800_change_gs_parameter_odbc_defaults.rb
@@ -0,0 +1,11 @@
+class ChangeGsParameterOdbcDefaults < ActiveRecord::Migration
+ def up
+ GsParameter.where(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'odbc-dsn').destroy_all
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'odbc-dsn', :value => 'default', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'odbc-dsn').destroy_all
+ GsParameter.create(:entity => 'sofia', :section => 'profile:gemeinschaft', :name => 'odbc-dsn', :value => 'gemeinschaft:gemeinschaft:gemeinschaft', :class_type => 'String')
+ end
+end
diff --git a/db/migrate/20130110085600_set_switch_parameters.rb b/db/migrate/20130110085600_set_switch_parameters.rb
new file mode 100644
index 0000000..85c3d64
--- /dev/null
+++ b/db/migrate/20130110085600_set_switch_parameters.rb
@@ -0,0 +1,21 @@
+class SetSwitchParameters < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'loglevel', :value => 'debug', :class_type => 'String')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'colorize-console', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'max-sessions', :value => 1000, :class_type => 'Integer')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'sessions-per-second', :value => 30, :class_type => 'Integer')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-enable-zrtp', :value => 'false', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-start-port', :value => 16384, :class_type => 'Integer')
+ GsParameter.create(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-end-port', :value => 32768, :class_type => 'Integer')
+ end
+
+ def down
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'loglevel').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'colorize-console').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'max-sessions').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'sessions-per-second').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-enable-zrtp').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-start-port').destroy_all
+ GsParameter.where(:entity => 'post_load_switch', :section => 'settings', :name => 'rtp-end-port').destroy_all
+ end
+end
diff --git a/db/migrate/20130110113500_set_conference_parameters.rb b/db/migrate/20130110113500_set_conference_parameters.rb
new file mode 100644
index 0000000..2de10c9
--- /dev/null
+++ b/db/migrate/20130110113500_set_conference_parameters.rb
@@ -0,0 +1,33 @@
+class SetConferenceParameters < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'mute', :value => '', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'deaf mute', :value => '*', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'energy up', :value => '9', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'energy equ', :value => '8', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'energy dn', :value => '7', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol talk up', :value => '3', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol talk zero', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol talk dn', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol listen up', :value => '6', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol listen zero', :value => '5', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'vol listen dn', :value => '4', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_speaker', :name => 'hangup', :value => '#', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'mute', :value => '0', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'deaf mute', :value => '*', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'energy up', :value => '9', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'energy equ', :value => '8', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'energy dn', :value => '7', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol talk up', :value => '3', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol talk zero', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol talk dn', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol listen up', :value => '6', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol listen zero', :value => '5', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'vol listen dn', :value => '4', :class_type => 'String')
+ GsParameter.create(:entity => 'conferences', :section => 'controls_moderator', :name => 'hangup', :value => '#', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:entity => 'conference', :section => 'controls_speaker').destroy_all
+ GsParameter.where(:entity => 'conference', :section => 'controls_moderator').destroy_all
+ end
+end
diff --git a/db/migrate/20130110133500_set_voicemail_parameters.rb b/db/migrate/20130110133500_set_voicemail_parameters.rb
new file mode 100644
index 0000000..3e7c192
--- /dev/null
+++ b/db/migrate/20130110133500_set_voicemail_parameters.rb
@@ -0,0 +1,45 @@
+class SetVoicemailParameters < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'file-extension', :value => 'wav', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'terminator-key', :value => '#', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'max-login-attempts', :value => '3', :class_type => 'Integer')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'digit-timeout', :value => '10000', :class_type => 'Integer')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'min-record-len', :value => '3', :class_type => 'Integer')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'max-record-len', :value => '300', :class_type => 'Integer')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'max-retries', :value => '3', :class_type => 'Integer')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'tone-spec', :value => '%(1000, 0, 640)', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'callback-dialplan', :value => 'XML', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'callback-context', :value => 'default', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'play-new-messages-key', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'play-saved-messages-key', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'login-keys', :value => '0', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'main-menu-key', :value => '0', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'config-menu-key', :value => '5', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'record-greeting-key', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'choose-greeting-key', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'change-pass-key', :value => '6', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'record-name-key', :value => '3', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'record-file-key', :value => '3', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'listen-file-key', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'save-file-key', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'delete-file-key', :value => '7', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'undelete-file-key', :value => '8', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'email-key', :value => '4', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'pause-key', :value => '0', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'restart-key', :value => '1', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'ff-key', :value => '6', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'rew-key', :value => '4', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'skip-greet-key', :value => '#', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'record-silence-threshold', :value => '200', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'record-silence-hits', :value => '2', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'operator-extension', :value => 'operator XML default', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'operator-key', :value => '9', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'vmain-extension', :value => 'vmain XML default', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'vmain-key', :value => '*', :class_type => 'String')
+ GsParameter.create(:entity => 'voicemail', :section => 'parameters', :name => 'odbc-dsn', :value => 'default', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:entity => 'voicemail', :section => 'parameters').destroy_all
+ end
+end
diff --git a/db/migrate/20130110205056_add_number_of_shown_items_to_gs_parameter.rb b/db/migrate/20130110205056_add_number_of_shown_items_to_gs_parameter.rb
new file mode 100644
index 0000000..72b477a
--- /dev/null
+++ b/db/migrate/20130110205056_add_number_of_shown_items_to_gs_parameter.rb
@@ -0,0 +1,9 @@
+class AddNumberOfShownItemsToGsParameter < ActiveRecord::Migration
+ def up
+ GsParameter.create(:name => 'NUMBER_OF_SHOWN_ITEMS', :section => 'Views', :value => '10', :class_type => 'Integer')
+ end
+
+ def down
+ GsParameter.where(:name => 'NUMBER_OF_SHOWN_ITEMS').destroy_all
+ end
+end
diff --git a/db/migrate/20130111111747_add_secret_token_to_gs_parameter.rb b/db/migrate/20130111111747_add_secret_token_to_gs_parameter.rb
new file mode 100644
index 0000000..bb99ace
--- /dev/null
+++ b/db/migrate/20130111111747_add_secret_token_to_gs_parameter.rb
@@ -0,0 +1,10 @@
+class AddSecretTokenToGsParameter < ActiveRecord::Migration
+ def up
+ require 'securerandom'
+ GsParameter.create(:name => 'SECRET_TOKEN', :section => 'Cookies', :value => SecureRandom.hex(64), :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:name => 'SECRET_TOKEN').destroy_all
+ end
+end
diff --git a/db/migrate/20130112073300_set_dialplan_variables.rb b/db/migrate/20130112073300_set_dialplan_variables.rb
new file mode 100644
index 0000000..3d538c0
--- /dev/null
+++ b/db/migrate/20130112073300_set_dialplan_variables.rb
@@ -0,0 +1,11 @@
+class SetDialplanVariables < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'dialplan', :section => 'variables', :name => 'ringback', :value => '%(2000,4000,440.0,480.0)', :class_type => 'String')
+ GsParameter.create(:entity => 'dialplan', :section => 'variables', :name => 'send_silence_when_idle', :value => 0, :class_type => 'Integer')
+ GsParameter.create(:entity => 'dialplan', :section => 'variables', :name => 'hold_music', :value => 'local_stream://moh', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:entity => 'dialplan', :section => 'variables').destroy_all
+ end
+end
diff --git a/db/migrate/20130112074800_remove_ringback_dialplan_parameter.rb b/db/migrate/20130112074800_remove_ringback_dialplan_parameter.rb
new file mode 100644
index 0000000..90b793d
--- /dev/null
+++ b/db/migrate/20130112074800_remove_ringback_dialplan_parameter.rb
@@ -0,0 +1,9 @@
+class RemoveRingbackDialplanParameter < ActiveRecord::Migration
+ def up
+ GsParameter.where(:entity => 'dialplan', :section => 'parameters', :name => 'ringback').destroy_all
+ end
+
+ def down
+ GsParameter.create(:entity => 'dialplan', :section => 'parameters', :name => 'ringback', :value => '%(2000,4000,440.0,480.0)', :class_type => 'String')
+ end
+end
diff --git a/db/migrate/20130112103337_set_new_value_for_provisioning_key_length.rb b/db/migrate/20130112103337_set_new_value_for_provisioning_key_length.rb
new file mode 100644
index 0000000..06d0ee8
--- /dev/null
+++ b/db/migrate/20130112103337_set_new_value_for_provisioning_key_length.rb
@@ -0,0 +1,9 @@
+class SetNewValueForProvisioningKeyLength < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => nil, :section => 'Provisioning', :name => 'PROVISIONING_KEY_LENGTH', :value => '12', :class_type => 'Integer')
+ end
+
+ def down
+ GsParameter.where(:name => 'PROVISIONING_KEY_LENGTH').destroy_all
+ end
+end
diff --git a/db/migrate/20130113072126_create_gateways.rb b/db/migrate/20130113072126_create_gateways.rb
new file mode 100644
index 0000000..e6c3f77
--- /dev/null
+++ b/db/migrate/20130113072126_create_gateways.rb
@@ -0,0 +1,16 @@
+class CreateGateways < ActiveRecord::Migration
+ def self.up
+ create_table :gateways do |t|
+ t.string :name
+ t.string :technology
+ t.boolean :inbound
+ t.boolean :outbound
+ t.string :description
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :gateways
+ end
+end
diff --git a/db/migrate/20130113073323_create_gateway_settings.rb b/db/migrate/20130113073323_create_gateway_settings.rb
new file mode 100644
index 0000000..0200ae7
--- /dev/null
+++ b/db/migrate/20130113073323_create_gateway_settings.rb
@@ -0,0 +1,16 @@
+class CreateGatewaySettings < ActiveRecord::Migration
+ def self.up
+ create_table :gateway_settings do |t|
+ t.integer :gateway_id
+ t.string :name
+ t.string :value
+ t.string :class_type
+ t.string :description
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :gateway_settings
+ end
+end
diff --git a/db/migrate/20130113090705_create_gateway_parameters.rb b/db/migrate/20130113090705_create_gateway_parameters.rb
new file mode 100644
index 0000000..bbf5f54
--- /dev/null
+++ b/db/migrate/20130113090705_create_gateway_parameters.rb
@@ -0,0 +1,16 @@
+class CreateGatewayParameters < ActiveRecord::Migration
+ def self.up
+ create_table :gateway_parameters do |t|
+ t.integer :gateway_id
+ t.string :name
+ t.string :value
+ t.string :class_type
+ t.string :description
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :gateway_parameters
+ end
+end
diff --git a/db/migrate/20130116133243_create_call_routes.rb b/db/migrate/20130116133243_create_call_routes.rb
new file mode 100644
index 0000000..c2feda8
--- /dev/null
+++ b/db/migrate/20130116133243_create_call_routes.rb
@@ -0,0 +1,16 @@
+class CreateCallRoutes < ActiveRecord::Migration
+ def self.up
+ create_table :call_routes do |t|
+ t.string :routing_table
+ t.string :name
+ t.string :endpoint_type
+ t.integer :endpoint_id
+ t.integer :position
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :call_routes
+ end
+end
diff --git a/db/migrate/20130116133433_create_route_elements.rb b/db/migrate/20130116133433_create_route_elements.rb
new file mode 100644
index 0000000..72f6894
--- /dev/null
+++ b/db/migrate/20130116133433_create_route_elements.rb
@@ -0,0 +1,19 @@
+class CreateRouteElements < ActiveRecord::Migration
+ def self.up
+ create_table :route_elements do |t|
+ t.integer :call_route_id
+ t.string :var_in
+ t.string :var_out
+ t.string :pattern
+ t.string :replacement
+ t.string :action
+ t.boolean :mandatory
+ t.integer :position
+ t.timestamps
+ end
+ end
+
+ def self.down
+ drop_table :route_elements
+ end
+end
diff --git a/db/migrate/20130116145500_set_routing_variables.rb b/db/migrate/20130116145500_set_routing_variables.rb
new file mode 100644
index 0000000..abd8fa6
--- /dev/null
+++ b/db/migrate/20130116145500_set_routing_variables.rb
@@ -0,0 +1,12 @@
+class SetRoutingVariables < ActiveRecord::Migration
+ def up
+ GsParameter.create(:entity => 'call_route', :section => 'failover', :name => '603', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'call_route', :section => 'failover', :name => '480', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'call_route', :section => 'failover', :name => 'UNALLOCATED_NUMBER', :value => 'true', :class_type => 'Boolean')
+ GsParameter.create(:entity => 'call_route', :section => 'failover', :name => 'NORMAL_TEMPORARY_FAILURE', :value => 'true', :class_type => 'Boolean')
+ end
+
+ def down
+ GsParameter.where(:entity => 'call_route', :section => 'failover').destroy_all
+ end
+end
diff --git a/db/migrate/20130116213312_change_user_name_prefix.rb b/db/migrate/20130116213312_change_user_name_prefix.rb
new file mode 100644
index 0000000..1e6aa59
--- /dev/null
+++ b/db/migrate/20130116213312_change_user_name_prefix.rb
@@ -0,0 +1,5 @@
+class ChangeUserNamePrefix < ActiveRecord::Migration
+ def up
+ GsParameter.where(:name => 'USER_NAME_PREFIX').first.update_attributes(:value => "xyz")
+ end
+end
diff --git a/db/migrate/20130117142600_change_action_prerouting_table.rb b/db/migrate/20130117142600_change_action_prerouting_table.rb
new file mode 100644
index 0000000..8b57ca6
--- /dev/null
+++ b/db/migrate/20130117142600_change_action_prerouting_table.rb
@@ -0,0 +1,13 @@
+class ChangeActionPreroutingTable < ActiveRecord::Migration
+ def up
+ RouteElement.where(:action => 'set_route_var', :mandatory => true).each do |route|
+ route.update_attributes(:action => 'match')
+ end
+ end
+
+ def down
+ RouteElement.where(:action => 'match', :mandatory => true).each do |route|
+ route.update_attributes(:action => 'set_route_var')
+ end
+ end
+end
diff --git a/db/migrate/20130117191840_change_column_name_in_call_route.rb b/db/migrate/20130117191840_change_column_name_in_call_route.rb
new file mode 100644
index 0000000..bbc4f28
--- /dev/null
+++ b/db/migrate/20130117191840_change_column_name_in_call_route.rb
@@ -0,0 +1,7 @@
+class ChangeColumnNameInCallRoute < ActiveRecord::Migration
+ def up
+ if column_exists?(:call_routes, :table)
+ rename_column :call_routes, :table, :routing_table
+ end
+ end
+end
diff --git a/db/migrate/20130121123742_add_default_area_code_to_gemeinschaft_setup.rb b/db/migrate/20130121123742_add_default_area_code_to_gemeinschaft_setup.rb
new file mode 100644
index 0000000..63a9fd1
--- /dev/null
+++ b/db/migrate/20130121123742_add_default_area_code_to_gemeinschaft_setup.rb
@@ -0,0 +1,5 @@
+class AddDefaultAreaCodeToGemeinschaftSetup < ActiveRecord::Migration
+ def change
+ add_column :gemeinschaft_setups, :default_area_code, :string
+ end
+end
diff --git a/db/migrate/20130122121100_add_gemeinschaft_buildname_to_gs_parameter.rb b/db/migrate/20130122121100_add_gemeinschaft_buildname_to_gs_parameter.rb
new file mode 100644
index 0000000..d4cd660
--- /dev/null
+++ b/db/migrate/20130122121100_add_gemeinschaft_buildname_to_gs_parameter.rb
@@ -0,0 +1,9 @@
+class AddGemeinschaftBuildnameToGsParameter < ActiveRecord::Migration
+ def up
+ GsParameter.create(:name => 'GEMEINSCHAFT_BUILDNAME', :section => 'Generic', :value => '', :class_type => 'String')
+ end
+
+ def down
+ GsParameter.where(:name => 'GEMEINSCHAFT_BUILDNAME').destroy_all
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 12114dc..649e022 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 => 20121230110747) do
+ActiveRecord::Schema.define(:version => 20130122121100) do
create_table "access_authorizations", :force => true do |t|
t.string "access_authorizationable_type"
@@ -176,6 +176,16 @@ ActiveRecord::Schema.define(:version => 20121230110747) do
t.datetime "updated_at", :null => false
end
+ create_table "call_routes", :force => true do |t|
+ t.string "routing_table"
+ t.string "name"
+ t.string "endpoint_type"
+ t.integer "endpoint_id"
+ t.integer "position"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
create_table "calls", :id => false, :force => true do |t|
t.string "call_uuid"
t.string "call_created", :limit => 128
@@ -490,13 +500,44 @@ ActiveRecord::Schema.define(:version => 20121230110747) do
t.integer "stop_time", :default => 0, :null => false
end
+ create_table "gateway_parameters", :force => true do |t|
+ t.integer "gateway_id"
+ t.string "name"
+ t.string "value"
+ t.string "class_type"
+ t.string "description"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ create_table "gateway_settings", :force => true do |t|
+ t.integer "gateway_id"
+ t.string "name"
+ t.string "value"
+ t.string "class_type"
+ t.string "description"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
+ create_table "gateways", :force => true do |t|
+ t.string "name"
+ t.string "technology"
+ t.boolean "inbound"
+ t.boolean "outbound"
+ t.string "description"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
create_table "gemeinschaft_setups", :force => true do |t|
t.integer "user_id"
t.integer "sip_domain_id"
t.integer "country_id"
t.integer "language_id"
- t.datetime "created_at", :null => false
- t.datetime "updated_at", :null => false
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "default_area_code"
end
create_table "gs_cluster_sync_log_entries", :force => true do |t|
@@ -526,6 +567,17 @@ ActiveRecord::Schema.define(:version => 20121230110747) do
t.datetime "last_sync"
end
+ create_table "gs_parameters", :force => true do |t|
+ t.string "name"
+ t.string "section"
+ t.text "value"
+ t.string "class_type"
+ t.string "description"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ t.string "entity"
+ end
+
create_table "gui_function_memberships", :force => true do |t|
t.integer "gui_function_id"
t.integer "user_group_id"
@@ -765,6 +817,19 @@ ActiveRecord::Schema.define(:version => 20121230110747) do
t.datetime "updated_at", :null => false
end
+ create_table "route_elements", :force => true do |t|
+ t.integer "call_route_id"
+ t.string "var_in"
+ t.string "var_out"
+ t.string "pattern"
+ t.string "replacement"
+ t.string "action"
+ t.boolean "mandatory"
+ t.integer "position"
+ t.datetime "created_at", :null => false
+ t.datetime "updated_at", :null => false
+ end
+
create_table "sessions", :force => true do |t|
t.string "session_id", :null => false
t.text "data"
diff --git a/db/to-dos/20120119160732_emergency_numbers_germany.rb b/db/to-dos/20120119160732_emergency_numbers_germany.rb
index 9dd9131..f0c02d9 100644
--- a/db/to-dos/20120119160732_emergency_numbers_germany.rb
+++ b/db/to-dos/20120119160732_emergency_numbers_germany.rb
@@ -11,7 +11,7 @@ class EmergencyNumbersGermany < ActiveRecord::Migration
################################################################
# Emergency numbers which shouldn't be used as extensions
################################################################
- notruf_nummern = germany.phone_number_ranges.find_or_create_by_name(SERVICE_NUMBERS)
+ notruf_nummern = germany.phone_number_ranges.find_or_create_by_name(GsParameter.get('SERVICE_NUMBERS'))
notruf_nummern.phone_numbers.find_or_create_by_name_and_number('Polizei', '110')
notruf_nummern.phone_numbers.find_or_create_by_name_and_number('Feuerwehr', '112')
notruf_nummern.phone_numbers.find_or_create_by_name_and_number('Zentrale Behördenrufnummer', '115')
@@ -25,6 +25,6 @@ class EmergencyNumbersGermany < ActiveRecord::Migration
def down
germany = Country.find_by_name('Germany')
- germany.phone_number_ranges.where(:name => SERVICE_NUMBERS).destroy_all
+ germany.phone_number_ranges.where(:name => GsParameter.get('SERVICE_NUMBERS')).destroy_all
end
end
diff --git a/install.sh b/install.sh
deleted file mode 100755
index b086f6f..0000000
--- a/install.sh
+++ /dev/null
@@ -1,214 +0,0 @@
-#!/bin/bash
-
-echo -e "Gemeinschaft Version 5.0 Installation for Debian Linux\n"
-
-GS_DIR="/opt/GS5"
-
-aptitude update
-
-# Ask for the Github account data
-#
-echo -e "github username:\n"
-read USERNAME
-
-echo -e "github password:\n"
-read PASSWORD
-
-# Upgrade everything to be on the safe side.
-#
-echo "Upgrade the server ..."
-aptitude upgrade
-
-# Install git
-#
-echo -e "Installing git ...\n"
-aptitude install -y git
-
-# Install the mysql server without asking for a password
-#
-echo "Installing MySQL server ..."
-apt-get install -y debconf-utils
-
-mysql_password=
-export DEBIAN_FRONTEND=noninteractive
-debconf-set-selections <<< 'mysql-server-5.1 mysql-server/root_password password '$mysql_password''
-debconf-set-selections <<< 'mysql-server-5.1 mysql-server/root_password_again password '$mysql_password''
-apt-get -y install mysql-server
-
-# Clone the git repository
-#
-echo -e "Downloading GS5 ...\n"
-
-cd /opt
-
-git clone "https://$USERNAME:$PASSWORD@github.com/amooma/GS5.git" "${GS_DIR}"
-
-if [ -f "${GS_DIR}/config/application.rb" ]
-then
- echo " OK"
-else
- echo " ERROR"
- exit 1
-fi
-
-echo -e "Installing GS5 dependencies ...\n"
-
-aptitude install -y \
- sqlite3 \
- libsqlite3-dev \
- libjpeg62 \
- ghostscript \
- imagemagick \
- libtiff-tools \
-
-cd /usr/local/src/
-
-wget "http://65.23.153.46/GS5/freeswitch_1.1.beta2.1-1_i386.deb"
-wget "http://65.23.153.46/GS5/freeswitch-lang-en_1.1.beta2.1-1_i386.deb"
-wget "http://65.23.153.46/GS5/freeswitch-lang-de_1.1.beta2.1-1_i386.deb"
-wget "http://65.23.153.46/GS5/freeswitch-lua_1.1.beta2.1-1_i386.deb"
-wget "http://65.23.153.46/GS5/unixodbc_2.3.1-1_i386.deb"
-wget "http://65.23.153.46/GS5/mysql-connector-odbc_5.1.11-1_i386.deb"
-wget "http://65.23.153.46/GS5/luasql_2.1.1-1_i386.deb"
-wget "http://files.freeswitch.org/freeswitch-sounds-en-us-callie-8000-1.0.16.tar.gz"
-wget "http://files.freeswitch.org/freeswitch-sounds-en-us-callie-16000-1.0.16.tar.gz"
-wget "http://files.freeswitch.org/freeswitch-sounds-music-8000-1.0.8.tar.gz"
-wget "http://files.freeswitch.org/freeswitch-sounds-music-16000-1.0.8.tar.gz"
-
-echo -e "Installing FreeSWITCH dependencies ...\n"
-
-aptitude install -y \
- libasound2 \
- libcurl3 \
- libogg0 \
- libvorbis0a
-
-echo -e "Installing FreeSWITCH ...\n"
-
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/freeswitch_1.1.beta2.1-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/freeswitch-lang-en_1.1.beta2.1-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/freeswitch-freeswitch-lang-de_1.1.beta2.1-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/freeswitch-lua_1.1.beta2.1-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/unixodbc_2.3.1-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/mysql-connector-odbc_5.1.11-1_i386.deb
-DEBIAN_FRONTEND=noninteractive dpkg -i /usr/local/src/luasql_2.1.1-1_i386.deb
-
-aptitude -f install
-
-sed -i 's/FREESWITCH_ENABLED="false"/FREESWITCH_ENABLED="true"/' /etc/default/freeswitch
-sed -i 's/^FREESWITCH_PARAMS.*/FREESWITCH_PARAMS="-nc"/' /etc/default/freeswitch
-
-echo -e "Installing Dependencies ...\n"
-
-aptitude -y install \
- curl \
- build-essential \
- libncurses5-dev \
- zlib1g-dev \
- libssl-dev \
- libreadline-dev \
- libcurl4-openssl-dev
-
-# Install RVM
-#
-bash < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
-
-source /etc/profile.d/rvm.sh
-
-rvm install 1.9.2
-rvm use 1.9.2 --default
-
-# Install stuff which is needed to build specific gems
-#
-apt-get -y install libmysqlclient15-dev
-apt-get -y install libxslt-dev libxml2-dev
-
-echo -e "Installing GS5 gems ...\n"
-cd "${GS_DIR}"
-bundle install
-
-echo -e "Setting up database ...\n"
-
-mysqladmin create gemeinschaft
-
-echo "[ODBC Drivers]
-MyODBC = Installed
-/usr/local/lib/libmyodbc5.so = Installed
-
-[gemeinschaft]
-Description = MySQL database for Gemeinschaft
-Driver = /usr/lib/libmyodbc5.so
-" >/usr/local/etc/odbcinst.ini
-
-echo "[gemeinschaft]
-Description = MySQL database for Gemeinschaft
-Driver = /usr/local/lib/libmyodbc5.so
-SERVER = localhost
-PORT = 3306
-DATABASE = gemeinschaft
-OPTION = 67108864
-USER = gemeinschaft
-PASSWORD = gemeinschaft
-" >/usr/local/etc/odbc.ini
-
-mysql -e "GRANT ALL PRIVILEGES ON gemeinschaft.* TO gemeinschaft @'%' IDENTIFIED BY 'gemeinschaft';"
-mysql -e "FLUSH PRIVILEGES"
-
-bundle exec rake db:migrate RAILS_ENV="production"
-
-echo -e "Extracting FreeSWITCH sounds ...\n"
-
-mkdir -p /opt/freeswitch/sounds
-cd /opt/freeswitch/sounds
-
-tar -xzf "/usr/local/src/freeswitch-sounds-en-us-callie-8000-1.0.16.tar.gz"
-tar -xzf "/usr/local/src/freeswitch-sounds-en-us-callie-16000-1.0.16.tar.gz"
-tar -xzf "/usr/local/src/freeswitch-sounds-music-8000-1.0.8.tar.gz"
-tar -xzf "/usr/local/src/freeswitch-sounds-music-16000-1.0.8.tar.gz"
-
-echo -e "Creating FreeSWITCH configuration ...\n"
-
-rm -fr /opt/freeswitch/conf
-rm -fr /opt/freeswitch/scripts
-
-ln -s "${GS_DIR}/misc/freeswitch/conf/" /opt/freeswitch/conf
-ln -s "${GS_DIR}/misc/freeswitch/scripts/" /opt/freeswitch/scripts
-
-echo -e "Setting up permissions ...\n"
-
-addgroup gemeinschaft || true
-adduser freeswitch gemeinschaft --quiet
-
-chgrp -R gemeinschaft "${GS_DIR}"
-chmod -R g+w "${GS_DIR}"
-
-# Create FreeSWITCH log directory
-mkdir /var/log/freeswitch/
-chown freeswitch:gemeinschaft /var/log/freeswitch/
-
-# Installation of nginx and passenger
-#
-apt-get -y install libpcre3-dev
-gem install passenger
-passenger-install-nginx-module --auto --auto-download --prefix=/opt/nginx
-
-rm -f /opt/nginx/conf/nginx.conf
-ln -s "${GS_DIR}/misc/nginx/nginx.conf" /opt/nginx/conf/nginx.conf
-
-adduser www-data gemeinschaft --quiet
-
-# Generate CSS
-#
-cd "${GS_DIR}"
-RAILS_ENV=production bundle exec rake assets:precompile
-
-echo "Done!"
-
-echo "You can start the webserver with /opt/nginx/sbin/nginx"
-
-
-# Ensure FreeSWITCH has permission to write to Fax directory
-#chmod -R g+w /opt/gemeinschaft/public/uploads/fax_document/
-#chgrp -R gemeinschaft /opt/gemeinschaft/public/uploads/fax_document/
-#chmod -R g+w /tmp/GS-5.0/
-#chgrp -R gemeinschaft /tmp/GS-5.0/
diff --git a/lib/activerecord_extensions.rb b/lib/activerecord_extensions.rb
index 50c44be..102ddd8 100644
--- a/lib/activerecord_extensions.rb
+++ b/lib/activerecord_extensions.rb
@@ -16,7 +16,7 @@ class ActiveRecord::Base
#
def populate_gs_node_id
if self.attribute_names.include?('gs_node_id') && self.gs_node_id.blank?
- self.gs_node_id = GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS).first.try(:id)
+ self.gs_node_id = GsNode.where(:ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS')).first.try(:id)
end
end
@@ -47,7 +47,7 @@ class ActiveRecord::Base
logger.error "Couldn't #{action} #{self.class} with the ID #{self.id} on other GsNodes because #{self.class} doesn't have a is_native attribute."
else
if self.is_native != false
- if defined? WRITE_GS_CLUSTER_SYNC_LOG && WRITE_GS_CLUSTER_SYNC_LOG == true
+ if defined? GsParameter.get('WRITE_GS_CLUSTER_SYNC_LOG') && GsParameter.get('WRITE_GS_CLUSTER_SYNC_LOG') == true
if !(defined? $gs_cluster_loop_protection) || $gs_cluster_loop_protection != true
begin
GsClusterSyncLogEntry.create(
@@ -55,7 +55,7 @@ class ActiveRecord::Base
:action => action,
:content => content,
:history => history,
- :homebase_ip_address => HOMEBASE_IP_ADDRESS,
+ :homebase_ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS'),
:waiting_to_be_synced => true,
:association_method => association_method,
:association_uuid => association_uuid
diff --git a/lib/bootstrap_breadcrumbs_builder.rb b/lib/bootstrap_breadcrumbs_builder.rb
new file mode 100644
index 0000000..1d6326b
--- /dev/null
+++ b/lib/bootstrap_breadcrumbs_builder.rb
@@ -0,0 +1,32 @@
+# The BootstrapBreadcrumbsBuilder is a Bootstrap compatible breadcrumb builder.
+# It provides basic functionalities to render a breadcrumb navigation according to Bootstrap's conventions.
+#
+# BootstrapBreadcrumbsBuilder accepts a limited set of options:
+# * separator: what should be displayed as a separator between elements
+#
+# You can use it with the :builder option on render_breadcrumbs:
+# <%= render_breadcrumbs :builder => ::BootstrapBreadcrumbsBuilder, :separator => "&raquo;" %>
+#
+# Note: You may need to adjust the autoload_paths in your config/application.rb file for rails to load this class:
+# config.autoload_paths += Dir["#{config.root}/lib/"]
+#
+class BootstrapBreadcrumbsBuilder < BreadcrumbsOnRails::Breadcrumbs::Builder
+ def render
+ @context.content_tag(:ul, class: 'breadcrumb') do
+ @elements.collect do |element|
+ render_element(element)
+ end.join.html_safe
+ end
+ end
+
+ def render_element(element)
+ current = @context.current_page?(compute_path(element))
+
+ @context.content_tag(:li, :class => ('active' if current)) do
+ link_or_text = @context.link_to_unless_current(compute_name(element), compute_path(element), element.options)
+ divider = @context.content_tag(:span, (@options[:separator] || '/').html_safe, :class => 'divider') unless current
+
+ link_or_text + (divider || '')
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml b/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml
index 4b43a3b..7f21ea3 100644
--- a/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml
+++ b/lib/generators/nifty/authentication/templates/views/haml/edit.html.haml
@@ -1,3 +1,3 @@
-- title "Sign up"
+- content_for :title, "Sign up"
= render "form"
diff --git a/lib/generators/nifty/authentication/templates/views/haml/login.html.haml b/lib/generators/nifty/authentication/templates/views/haml/login.html.haml
index 22fc95b..3aebb44 100644
--- a/lib/generators/nifty/authentication/templates/views/haml/login.html.haml
+++ b/lib/generators/nifty/authentication/templates/views/haml/login.html.haml
@@ -1,4 +1,4 @@
-- title "Log in"
+- content_for :title, "Log in"
%p== Don't have an account? #{link_to "Sign up!", signup_path}
diff --git a/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml b/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml
index dc75c13..8557204 100644
--- a/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml
+++ b/lib/generators/nifty/authentication/templates/views/haml/signup.html.haml
@@ -1,4 +1,4 @@
-- title "Sign up"
+- content_for :title, "Sign up"
%p== Already have an account? #{link_to "Log in", login_path}.
diff --git a/lib/generators/nifty/scaffold/templates/views/haml/_index_core.html.haml b/lib/generators/nifty/scaffold/templates/views/haml/_index_core.html.haml
index 9cbea63..a523d32 100644
--- a/lib/generators/nifty/scaffold/templates/views/haml/_index_core.html.haml
+++ b/lib/generators/nifty/scaffold/templates/views/haml/_index_core.html.haml
@@ -1,12 +1,12 @@
-%table
+%table{:class => 'table table-striped'}
%tr
<%- for attribute in model_attributes -%>
%th= t('<%= plural_name %>.index.<%= attribute.name %>')
<%- end -%>
- - reset_cycle
+
- for <%= instance_name %> in <%= instances_name %>
- %tr{:class => cycle('odd', 'even')}
+ %tr
<%- for attribute in model_attributes -%>
%td= <%= instance_name %>.<%= attribute.name %>
<%- end -%>
diff --git a/lib/generators/nifty/scaffold/templates/views/haml/edit.html.haml b/lib/generators/nifty/scaffold/templates/views/haml/edit.html.haml
index dc7de62..381fba0 100644
--- a/lib/generators/nifty/scaffold/templates/views/haml/edit.html.haml
+++ b/lib/generators/nifty/scaffold/templates/views/haml/edit.html.haml
@@ -1,3 +1,3 @@
-- title t("<%= plural_name %>.edit.page_title")
+- content_for :title, t("<%= plural_name %>.edit.page_title")
<%= render_form %> \ No newline at end of file
diff --git a/lib/generators/nifty/scaffold/templates/views/haml/index.html.haml b/lib/generators/nifty/scaffold/templates/views/haml/index.html.haml
index 86c6b9e..b6642ad 100644
--- a/lib/generators/nifty/scaffold/templates/views/haml/index.html.haml
+++ b/lib/generators/nifty/scaffold/templates/views/haml/index.html.haml
@@ -1,4 +1,4 @@
-- title t("<%= plural_name %>.index.page_title")
+- content_for :title, t("<%= plural_name %>.index.page_title")
- if @<%= instances_name %> && @<%= instances_name %>.count > 0
= render "index_core", :<%= instances_name %> => @<%= instances_name %>
diff --git a/lib/generators/nifty/scaffold/templates/views/haml/new.html.haml b/lib/generators/nifty/scaffold/templates/views/haml/new.html.haml
index 4e7f871..d9a6bb5 100644
--- a/lib/generators/nifty/scaffold/templates/views/haml/new.html.haml
+++ b/lib/generators/nifty/scaffold/templates/views/haml/new.html.haml
@@ -1,3 +1,3 @@
-- title t("<%= plural_name %>.new.page_title")
+- content_for :title, t("<%= plural_name %>.new.page_title")
<%= render_form %> \ No newline at end of file
diff --git a/lib/generators/nifty/scaffold/templates/views/haml/show.html.haml b/lib/generators/nifty/scaffold/templates/views/haml/show.html.haml
index 3d01340..bd73c52 100644
--- a/lib/generators/nifty/scaffold/templates/views/haml/show.html.haml
+++ b/lib/generators/nifty/scaffold/templates/views/haml/show.html.haml
@@ -1,4 +1,4 @@
-- title t("<%= plural_name %>.show.page_title")
+- content_for :title, t("<%= plural_name %>.show.page_title")
<%- for attribute in model_attributes -%>
%p
diff --git a/lib/tasks/cvs_user_import.rake b/lib/tasks/cvs_user_import.rake
index 2475a43..81959d5 100644
--- a/lib/tasks/cvs_user_import.rake
+++ b/lib/tasks/cvs_user_import.rake
@@ -24,14 +24,14 @@ namespace :user_import do
# Read the CSV data and store them in the new_users hash.
#
- csv_data = CSV.read(IMPORT_CSV_FILE, encoding: IMPORT_CSV_ENCODING)
+ csv_data = CSV.read(GsParameter.get('IMPORT_CSV_FILE'), encoding: GsParameter.get('IMPORT_CSV_ENCODING'))
headers = csv_data.shift.map {|i| i.to_s }
string_data = csv_data.map {|row| row.map {|cell| cell.to_s } }
new_users = string_data.map {|row| Hash[*headers.zip(row).flatten] }
- gs_node_id = GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS).first.try(:id)
+ gs_node_id = GsNode.where(:ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS')).first.try(:id)
- if File.exists?(DOUBLE_CHECK_POSITIVE_USERS_CSV)
- csv_data = CSV.read(DOUBLE_CHECK_POSITIVE_USERS_CSV, encoding: IMPORT_CSV_ENCODING)
+ if File.exists?(GsParameter.get('DOUBLE_CHECK_POSITIVE_USERS_CSV'))
+ csv_data = CSV.read(GsParameter.get('DOUBLE_CHECK_POSITIVE_USERS_CSV'), encoding: GsParameter.get('IMPORT_CSV_ENCODING'))
if csv_data.blank?
double_checked_user_names = []
else
@@ -45,13 +45,13 @@ namespace :user_import do
double_checked_user_names = new_users.map{|user| user['UserName']}
end
- tenant = Tenant.find(DEFAULT_API_TENANT_ID)
+ tenant = Tenant.find(GsParameter.get('DEFAULT_API_TENANT_ID'))
# Destroy deleted user by making a diff of where(:importer_checksum)
# and users in the CSV file.
#
- if defined?(USER_NAME_PREFIX) && !USER_NAME_PREFIX.blank?
- new_users_user_names = new_users.map{|x| USER_NAME_PREFIX.to_s + x['UserName'].to_s}
+ if defined?(GsParameter.get('USER_NAME_PREFIX')) && !GsParameter.get('USER_NAME_PREFIX').blank?
+ new_users_user_names = new_users.map{|x| GsParameter.get('USER_NAME_PREFIX').to_s + x['UserName'].to_s}
else
new_users_user_names = new_users.map{|x| x['UserName']}
end
@@ -67,8 +67,8 @@ namespace :user_import do
new_users.each do |csv_user|
if !(csv_user['UserName'].blank? || csv_user['Email'].blank?) && double_checked_user_names.include?(csv_user['UserName'])
csv_user['Email'] = csv_user['Email'].downcase
- if defined?(USER_NAME_PREFIX) && !USER_NAME_PREFIX.blank?
- csv_user['UserName'] = USER_NAME_PREFIX.to_s + csv_user['UserName']
+ if defined?(GsParameter.get('USER_NAME_PREFIX')) && !GsParameter.get('USER_NAME_PREFIX').blank?
+ csv_user['UserName'] = GsParameter.get('USER_NAME_PREFIX').to_s + csv_user['UserName']
end
md5_sum = Digest::MD5.hexdigest(csv_user.to_yaml)
@@ -177,7 +177,7 @@ namespace :user_import do
if phone_numbers_count < sip_account.phone_numbers.count
call_forward_case_offline = CallForwardCase.find_by_value('offline')
if call_forward_case_offline
- sip_account.phone_numbers.first.call_forwards.create(:call_forward_case_id => call_forward_case_offline.id, :call_forwardable_type => 'Voicemail', :active => true, :depth => DEFAULT_CALL_FORWARD_DEPTH)
+ sip_account.phone_numbers.first.call_forwards.create(:call_forward_case_id => call_forward_case_offline.id, :call_forwardable_type => 'Voicemail', :active => true, :depth => GsParameter.get('DEFAULT_CALL_FORWARD_DEPTH'))
end
end
else
@@ -280,8 +280,8 @@ namespace :user_import do
conference.start = nil
conference.end = nil
conference.open_for_anybody = true
- conference.max_members = DEFAULT_MAX_CONFERENCE_MEMBERS
- conference.pin = (1..MINIMUM_PIN_LENGTH).map{|i| (0 .. 9).to_a.sample}.join
+ conference.max_members = GsParameter.get('DEFAULT_MAX_CONFERENCE_MEMBERS')
+ conference.pin = (1..GsParameter.get('MINIMUM_PIN_LENGTH')).map{|i| (0 .. 9).to_a.sample}.join
conference.save
end
@@ -314,7 +314,7 @@ namespace :user_import do
cell_phone_number = csv_user['CellPhone'].to_s.gsub(/[^0-9\+]/, '')
if !cell_phone_number.blank?
- callthrough = tenant.callthroughs.find_or_create_by_name(CALLTHROUGH_NAME_TO_BE_USED_FOR_DEFAULT_ACTIVATION)
+ callthrough = tenant.callthroughs.find_or_create_by_name(GsParameter.get('CALLTHROUGH_NAME_TO_BE_USED_FOR_DEFAULT_ACTIVATION'))
access_authorization = callthrough.access_authorizations.find_or_create_by_name('Cellphones')
diff --git a/lib/tasks/fax.rake b/lib/tasks/fax.rake
index 1f1c282..41ae7cf 100644
--- a/lib/tasks/fax.rake
+++ b/lib/tasks/fax.rake
@@ -37,7 +37,7 @@ task :import_inbound_fax, [
-o \"#{pdf_file}\" \\
-p #{paper_size} \\
-a \"#{fax_arguments[:remote_station_id]}\" \\
- -c \"AMOOMA Gemeinschaft version #{GEMEINSCHAFT_VERSION}\" \\
+ -c \"AMOOMA Gemeinschaft version #{GsParameter.get('GEMEINSCHAFT_VERSION')}\" \\
-t \"#{fax_arguments[:remote_station_id]}\" \"#{tiff_file}\""
if !File.exists?( pdf_file )
diff --git a/lib/tasks/gs_cluster.rake b/lib/tasks/gs_cluster.rake
index 565fd83..7b49ebb 100644
--- a/lib/tasks/gs_cluster.rake
+++ b/lib/tasks/gs_cluster.rake
@@ -1,15 +1,15 @@
namespace :gs_cluster do
desc "Sync local data to other gs cluster nodes."
task :push_waiting_data_to_other_nodes => :environment do
- infinity_loop_protection_counter = GsClusterSyncLogEntry.where(:homebase_ip_address => HOMEBASE_IP_ADDRESS,
+ infinity_loop_protection_counter = GsClusterSyncLogEntry.where(:homebase_ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS'),
:waiting_to_be_synced => true).count + 10
# One bite at a time.
#
- while GsClusterSyncLogEntry.where(:homebase_ip_address => HOMEBASE_IP_ADDRESS,
+ while GsClusterSyncLogEntry.where(:homebase_ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS'),
:waiting_to_be_synced => true).any? &&
infinity_loop_protection_counter > 0
- GsClusterSyncLogEntry.where(:homebase_ip_address => HOMEBASE_IP_ADDRESS,
+ GsClusterSyncLogEntry.where(:homebase_ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS'),
:waiting_to_be_synced => true).first.populate_other_cluster_nodes
infinity_loop_protection_counter -= 1
end
@@ -38,7 +38,7 @@ namespace :gs_cluster do
desc "Pull objects from nodes."
task :pull => :environment do
- local_node = GsNode.where(:ip_address => HOMEBASE_IP_ADDRESS).first
+ local_node = GsNode.where(:ip_address => GsParameter.get('HOMEBASE_IP_ADDRESS')).first
GsNode.where(:accepts_updates_from => true).each do |remote_node|
if remote_node.id == local_node.id
next
diff --git a/lib/tasks/heater.rake b/lib/tasks/heater.rake
new file mode 100644
index 0000000..11862a5
--- /dev/null
+++ b/lib/tasks/heater.rake
@@ -0,0 +1,17 @@
+namespace :heater do
+ desc "Warm up the cache."
+ task :preheat => :environment do
+ if GemeinschaftSetup.any?
+
+ else
+ # This is a fresh installation.
+ #
+ if Rails.env.production?
+ require 'open-uri'
+ open('/dev/null', 'wb') do |file|
+ file << open("http://localhost/gemeinschaft_setups/new").read
+ end
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/tasks/send_fax_notifications.rake b/lib/tasks/send_fax_notifications.rake
index 039c509..2ac74c8 100644
--- a/lib/tasks/send_fax_notifications.rake
+++ b/lib/tasks/send_fax_notifications.rake
@@ -23,7 +23,7 @@ task :send_fax_notifications => :environment do
-o \"#{pdf_file}\" \\
-p #{paper_size} \\
-a \"#{fax_document.remote_station_id}\" \\
- -c \"AMOOMA Gemeinschaft version #{GEMEINSCHAFT_VERSION}\" \\
+ -c \"AMOOMA Gemeinschaft version #{GsParameter.get('GEMEINSCHAFT_VERSION')}\" \\
-t \"#{fax_document.remote_station_id}\" \"#{TMP_DIR}#{tiff_file}\""
if !File.exists?( pdf_file )
diff --git a/lib/templates/erb/scaffold/_form.html.erb b/lib/templates/erb/scaffold/_form.html.erb
index 24a1768..201a069 100644
--- a/lib/templates/erb/scaffold/_form.html.erb
+++ b/lib/templates/erb/scaffold/_form.html.erb
@@ -1,13 +1,13 @@
<%%= simple_form_for(@<%= singular_table_name %>) do |f| %>
<%%= f.error_notification %>
- <div class="inputs">
+ <div class="form-inputs">
<%- attributes.each do |attribute| -%>
<%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
<%- end -%>
</div>
- <div class="actions">
+ <div class="form-actions">
<%%= f.button :submit %>
</div>
<%% end %>
diff --git a/misc/TODO-Liste.txt b/misc/TODO-Liste.txt
deleted file mode 100644
index e69de29..0000000
--- a/misc/TODO-Liste.txt
+++ /dev/null
diff --git a/misc/etc/cron.d/logout_phones b/misc/etc/cron.d/logout_phones
deleted file mode 100644
index 86b0ffd..0000000
--- a/misc/etc/cron.d/logout_phones
+++ /dev/null
@@ -1,3 +0,0 @@
-# Logout tagged phones
-23 1 * * * root /opt/GS5/script/logout_phones.sh
-
diff --git a/misc/etc/ssl/amooma/server.pem b/misc/etc/ssl/amooma/server.pem
deleted file mode 100644
index d34e8db..0000000
--- a/misc/etc/ssl/amooma/server.pem
+++ /dev/null
@@ -1,36 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDC9G3px4ew18PHIm8HJ3yXc9rxqM5uSn1qhjdoWM0zC0Qcue9k
-V+5ZUq356yjBbs5wXi3SEWfucXxhnwnzeIqvMeO6y0BiUVsClbqziRCho/hgHPTJ
-tZzjt6Mpl3D/9yeFKbah5lJ5qNm0T00ybpcSXC7w2Xv9ckji1DDtGo62fQIDAQAB
-AoGAHM0jl9AEednGcJrjsDjjLTTOebkolh6nHJ+re9zyo8HcVCob9cUPz15pmWxm
-Xv1RvkQLnOc5ZX6ak4l9XNzIEAvQXNRFXwCOyfpffx/8QhfrG0v2G+K2QG52VxQj
-tqnRdLf8HEhCmrJCMvMEAuQkAiirIMTFcaaP1CBbCilr8nkCQQDnSYxEfXMYi4iq
-9Xjwn8Ayh1koXFUY+5/0u9SGqzTeTxW1QN2hGhehsd0vlv4cJppcuL4Z+2VYqLQc
-zXDZo/MLAkEA18kSHLp+HCd1BW/JEoIQqWlTw6SRx+IsUN7UmnSZS4C+UPRbtq5I
-nzgzonZufOEmzoMdwbe9EHAl087f0UfxlwJBAKNIBhGYKvgqEdr3n2Dotuw1J1la
-De2sPpmtPPWxyoojdOTYHV8Np59MjSV6yHyhOBq7heGb3EmCGF25H7FWkE8CQGUN
-aakAgPxoUfn4zp4XQPxFMhAF6qtDtOMuZzvp7LwaD4ZT2PtlBOdjZ3LmqXlb61N8
-vZuxkx22l1BoqhIU8gMCQQDJsQr5y8UWamYZrNv5YRNnm8aGgJ83Gx3n5b8bKqjh
-TM8hqJfFTIfHr90GhHyok1aVkjF+sUtydX1R85IHTDz5
------END RSA PRIVATE KEY-----
------BEGIN CERTIFICATE-----
-MIIDfjCCAuegAwIBAgIJAKG1XaHFZ4gEMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
-VQQGEwJERTEYMBYGA1UECBMPUmhlaW5sYW5kLVBmYWx6MRAwDgYDVQQHEwdOZXV3
-aWVkMRQwEgYDVQQKEwtBTU9PTUEgR21iSDEXMBUGA1UEAxMOR2VtZWluc2NoYWZ0
-IDQxHTAbBgkqhkiG9w0BCQEWDmluZm9AYW1vb21hLmRlMB4XDTExMDcyMjE0NDAy
-OFoXDTIxMDcxOTE0NDAyOFowgYcxCzAJBgNVBAYTAkRFMRgwFgYDVQQIEw9SaGVp
-bmxhbmQtUGZhbHoxEDAOBgNVBAcTB05ldXdpZWQxFDASBgNVBAoTC0FNT09NQSBH
-bWJIMRcwFQYDVQQDEw5HZW1laW5zY2hhZnQgNDEdMBsGCSqGSIb3DQEJARYOaW5m
-b0BhbW9vbWEuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAML0benHh7DX
-w8cibwcnfJdz2vGozm5KfWqGN2hYzTMLRBy572RX7llSrfnrKMFuznBeLdIRZ+5x
-fGGfCfN4iq8x47rLQGJRWwKVurOJEKGj+GAc9Mm1nOO3oymXcP/3J4UptqHmUnmo
-2bRPTTJulxJcLvDZe/1ySOLUMO0ajrZ9AgMBAAGjge8wgewwHQYDVR0OBBYEFATl
-qWtGbyeBIN9mR/4GV9jO7ON7MIG8BgNVHSMEgbQwgbGAFATlqWtGbyeBIN9mR/4G
-V9jO7ON7oYGNpIGKMIGHMQswCQYDVQQGEwJERTEYMBYGA1UECBMPUmhlaW5sYW5k
-LVBmYWx6MRAwDgYDVQQHEwdOZXV3aWVkMRQwEgYDVQQKEwtBTU9PTUEgR21iSDEX
-MBUGA1UEAxMOR2VtZWluc2NoYWZ0IDQxHTAbBgkqhkiG9w0BCQEWDmluZm9AYW1v
-b21hLmRlggkAobVdocVniAQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB
-gQCBIgWoP8YiP6tm8rhb81k6myP4ONO4vOaUz9bsadHDWNCTjiQxvo4uVYqTMLKa
-Bc7S0VpyvSg7/eGsSWxIUwdn6dUPdo51juGnnJ9dK9DuiNPHb0HP3UJo1gCWgs1v
-EnVGfKDdu9FfdNcQtIb28UfF8Pw8WA6mmhQOOh0M9d3ayQ==
------END CERTIFICATE-----
diff --git a/misc/etc/ssl/amooma/server_cert.pem b/misc/etc/ssl/amooma/server_cert.pem
deleted file mode 100644
index 021ad28..0000000
--- a/misc/etc/ssl/amooma/server_cert.pem
+++ /dev/null
@@ -1,22 +0,0 @@
------BEGIN CERTIFICATE-----
-MIIDfjCCAuegAwIBAgIJAKG1XaHFZ4gEMA0GCSqGSIb3DQEBBQUAMIGHMQswCQYD
-VQQGEwJERTEYMBYGA1UECBMPUmhlaW5sYW5kLVBmYWx6MRAwDgYDVQQHEwdOZXV3
-aWVkMRQwEgYDVQQKEwtBTU9PTUEgR21iSDEXMBUGA1UEAxMOR2VtZWluc2NoYWZ0
-IDQxHTAbBgkqhkiG9w0BCQEWDmluZm9AYW1vb21hLmRlMB4XDTExMDcyMjE0NDAy
-OFoXDTIxMDcxOTE0NDAyOFowgYcxCzAJBgNVBAYTAkRFMRgwFgYDVQQIEw9SaGVp
-bmxhbmQtUGZhbHoxEDAOBgNVBAcTB05ldXdpZWQxFDASBgNVBAoTC0FNT09NQSBH
-bWJIMRcwFQYDVQQDEw5HZW1laW5zY2hhZnQgNDEdMBsGCSqGSIb3DQEJARYOaW5m
-b0BhbW9vbWEuZGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAML0benHh7DX
-w8cibwcnfJdz2vGozm5KfWqGN2hYzTMLRBy572RX7llSrfnrKMFuznBeLdIRZ+5x
-fGGfCfN4iq8x47rLQGJRWwKVurOJEKGj+GAc9Mm1nOO3oymXcP/3J4UptqHmUnmo
-2bRPTTJulxJcLvDZe/1ySOLUMO0ajrZ9AgMBAAGjge8wgewwHQYDVR0OBBYEFATl
-qWtGbyeBIN9mR/4GV9jO7ON7MIG8BgNVHSMEgbQwgbGAFATlqWtGbyeBIN9mR/4G
-V9jO7ON7oYGNpIGKMIGHMQswCQYDVQQGEwJERTEYMBYGA1UECBMPUmhlaW5sYW5k
-LVBmYWx6MRAwDgYDVQQHEwdOZXV3aWVkMRQwEgYDVQQKEwtBTU9PTUEgR21iSDEX
-MBUGA1UEAxMOR2VtZWluc2NoYWZ0IDQxHTAbBgkqhkiG9w0BCQEWDmluZm9AYW1v
-b21hLmRlggkAobVdocVniAQwDAYDVR0TBAUwAwEB/zANBgkqhkiG9w0BAQUFAAOB
-gQCBIgWoP8YiP6tm8rhb81k6myP4ONO4vOaUz9bsadHDWNCTjiQxvo4uVYqTMLKa
-Bc7S0VpyvSg7/eGsSWxIUwdn6dUPdo51juGnnJ9dK9DuiNPHb0HP3UJo1gCWgs1v
-EnVGfKDdu9FfdNcQtIb28UfF8Pw8WA6mmhQOOh0M9d3ayQ==
------END CERTIFICATE-----
-
diff --git a/misc/etc/ssl/amooma/server_key.pem b/misc/etc/ssl/amooma/server_key.pem
deleted file mode 100644
index 0c8e74e..0000000
--- a/misc/etc/ssl/amooma/server_key.pem
+++ /dev/null
@@ -1,16 +0,0 @@
------BEGIN RSA PRIVATE KEY-----
-MIICXQIBAAKBgQDC9G3px4ew18PHIm8HJ3yXc9rxqM5uSn1qhjdoWM0zC0Qcue9k
-V+5ZUq356yjBbs5wXi3SEWfucXxhnwnzeIqvMeO6y0BiUVsClbqziRCho/hgHPTJ
-tZzjt6Mpl3D/9yeFKbah5lJ5qNm0T00ybpcSXC7w2Xv9ckji1DDtGo62fQIDAQAB
-AoGAHM0jl9AEednGcJrjsDjjLTTOebkolh6nHJ+re9zyo8HcVCob9cUPz15pmWxm
-Xv1RvkQLnOc5ZX6ak4l9XNzIEAvQXNRFXwCOyfpffx/8QhfrG0v2G+K2QG52VxQj
-tqnRdLf8HEhCmrJCMvMEAuQkAiirIMTFcaaP1CBbCilr8nkCQQDnSYxEfXMYi4iq
-9Xjwn8Ayh1koXFUY+5/0u9SGqzTeTxW1QN2hGhehsd0vlv4cJppcuL4Z+2VYqLQc
-zXDZo/MLAkEA18kSHLp+HCd1BW/JEoIQqWlTw6SRx+IsUN7UmnSZS4C+UPRbtq5I
-nzgzonZufOEmzoMdwbe9EHAl087f0UfxlwJBAKNIBhGYKvgqEdr3n2Dotuw1J1la
-De2sPpmtPPWxyoojdOTYHV8Np59MjSV6yHyhOBq7heGb3EmCGF25H7FWkE8CQGUN
-aakAgPxoUfn4zp4XQPxFMhAF6qtDtOMuZzvp7LwaD4ZT2PtlBOdjZ3LmqXlb61N8
-vZuxkx22l1BoqhIU8gMCQQDJsQr5y8UWamYZrNv5YRNnm8aGgJ83Gx3n5b8bKqjh
-TM8hqJfFTIfHr90GhHyok1aVkjF+sUtydX1R85IHTDz5
------END RSA PRIVATE KEY-----
-
diff --git a/misc/example/apache-gs5.conf b/misc/example/apache-gs5.conf
deleted file mode 100644
index ef81952..0000000
--- a/misc/example/apache-gs5.conf
+++ /dev/null
@@ -1,24 +0,0 @@
-
- LoadModule passenger_module /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.11/ext/apache2/mod_passenger.so
- PassengerRoot /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.11
- PassengerRuby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby
-
-
-
- <VirtualHost *:443>
- ErrorLog "|/usr/bin/logger -t apache -i -p local6.notice"
- CustomLog "|/usr/bin/logger -t apache -i -p local6.notice" combined
-
-
- DocumentRoot /opt/GS5/public
- PassengerAppRoot /opt/GS5
- RailsEnv development
- <Directory /opt/GS5/public>
- AllowOverride all
- Options -MultiViews
- Options FollowSymLinks
- </Directory>
- SSLEngine on
- SSLCertificateFile /etc/ssl/amooma/server_cert.pem
- SSLCertificateKeyFile /etc/ssl/amooma/server_key.pem
- </VirtualHost>
diff --git a/misc/example/nginx b/misc/example/nginx
deleted file mode 100644
index ccb2bbb..0000000
--- a/misc/example/nginx
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/sh
-
-#####################################################################
-# nginx
-# Start Script
-# (c) AMOOMA GmbH 2012
-#####################################################################
-
-### BEGIN INIT INFO
-# Provides: nginx
-# Required-Start: freeswitch
-# Required-Stop: freeswitch
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: starts nginx
-# Description: starts nginx
-#
-### END INIT INFO
-
-DAEMON=/opt/nginx/sbin/nginx
-EXECUTABLE=`basename 'nginx'`
-NAME=nginx
-DESC=nginx
-ARGS=""
-
-if ! [ -x $DAEMON ] ; then
- echo "ERROR: $DAEMON not found"
- exit 1
-fi
-
-set -e
-
-. /lib/lsb/init-functions
-
-case "$1" in
- start)
- echo -n "Starting $DESC: "
- start-stop-daemon --start --quiet --pidfile /opt/nginx/logs/$NAME.pid \
- --exec $DAEMON -- $DAEMON_OPTS
- echo "$NAME."
- ;;
- stop)
- echo -n "Stopping $DESC: "
- start-stop-daemon --stop --quiet --pidfile /opt/nginx/logs/$NAME.pid \
- --exec $DAEMON
- echo "$NAME."
- ;;
- restart|force-reload)
- echo -n "Restarting $DESC: "
- start-stop-daemon --stop --quiet --pidfile \
- /opt/nginx/logs/$NAME.pid --exec $DAEMON
- sleep 1
- start-stop-daemon --start --quiet --pidfile \
- /opt/nginx/logs/$NAME.pid --exec $DAEMON -- $DAEMON_OPTS
- echo "$NAME."
- ;;
- reload)
- echo -n "Reloading $DESC configuration: "
- start-stop-daemon --stop --signal HUP --quiet --pidfile /opt/nginx/logs/$NAME.pid \
- --exec $DAEMON
- echo "$NAME."
- ;;
- status)
- status_of_proc -p /opt/nginx/logs/$NAME.pid "$DAEMON" nginx
- ;;
- *)
- N=/etc/init.d/$NAME
- echo "Usage: $N {start|stop|restart|reload|force-reload|status}" >&2
- exit 1
- ;;
-esac
-
-exit 0
diff --git a/misc/example/xml-interface.txt b/misc/example/xml-interface.txt
deleted file mode 100644
index 9f05540..0000000
--- a/misc/example/xml-interface.txt
+++ /dev/null
@@ -1,25 +0,0 @@
-User anlegen
-============
-
-echo '<row><UserName>2222</UserName><LastName>Meyer</LastName><FirstName>Fritz</FirstName><PhoneOffice>+49 228 1234567</PhoneOffice><VoipNr>665544</VoipNr><CellPhone>+49 171 123456</CellPhone><Fax>+49 228 1234444</Fax><Email>fritz.meier@example.com</Email><PIN>123456</PIN><PIN_LastUpdate>2010-11-22T07:09:07.5256939</PIN_LastUpdate><Photo>example.jpg</Photo></row>' | curl -X POST -H 'Content-type: text/xml' -d @- http://0.0.0.0:3000/api/rows
-
-Userdaten abrufen
-=================
-curl -H 'Content-type: text/xml' http://0.0.0.0:3000/api/rows/1.xml
-
-User löschen
-============
-
-curl -i -H "Accept: application/xml" -X DELETE http://0.0.0.0:3000/api/rows/1
-
-If only the user name is known:
-curl -i -H "Accept: application/xml" -X DELETE http://0.0.0.0:3000/api/rows/999999?user_name=12345
-
-
-User updaten
-============
-
-curl -i -X PUT -H 'Content-Type: application/xml' -d '<row><PhoneOffice>+49 228 5555555</PhoneOffice><VoipNr>665544</VoipNr></row>' http://localhost:3000/api/rows/1
-
-If only the user name is known:
-curl -i -X PUT -H 'Content-Type: application/xml' -d '<row><PhoneOffice>+49 228 5555555</PhoneOffice><VoipNr>665544</VoipNr></row>' http://localhost:3000/api/rows/999999?user_name=12345 \ No newline at end of file
diff --git a/misc/freeswitch/conf/freeswitch.xml b/misc/freeswitch/conf/freeswitch.xml
index 04369a7..3c098fc 100644
--- a/misc/freeswitch/conf/freeswitch.xml
+++ b/misc/freeswitch/conf/freeswitch.xml
@@ -1,10 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="freeswitch/xml">
<X-PRE-PROCESS cmd="set" data="sound_prefix=/opt/freeswitch/sounds/en/us/callie"/>
- <X-PRE-PROCESS cmd="set" data="hold_music=local_stream://moh"/>
- <X-PRE-PROCESS cmd="set" data="use_profile=internal"/>
- <X-PRE-PROCESS cmd="set" data="send_silence_when_idle=400"/>
- <X-PRE-PROCESS cmd="set" data="de-ring=%(1000,4000,425.0)"/>
<section name="languages" description="Language Management">
<language name="en" say-module="en" sound-prefix="/opt/freeswitch/sounds/en/us/callie">
<phrases>
@@ -495,29 +491,22 @@
<param name="listen-port" value="8021"/>
</settings>
</configuration>
- <configuration name="fifo.conf" description="FIFO Configuration">
- <settings>
- <param name="delete-all-outbound-member-on-startup" value="false"/>
- </settings>
- <fifos>
- </fifos>
- </configuration>
<configuration name="local_stream.conf" description="stream files from local dir">
- <directory name="default" path="/opt/freeswitch/sounds/music/16000">
- <param name="rate" value="16000"/>
+ <directory name="default" path="/opt/freeswitch/sounds/music/8000">
+ <param name="rate" value="8000"/>
<param name="shuffle" value="true"/>
<param name="channels" value="1"/>
<param name="interval" value="20"/>
<param name="timer-name" value="soft"/>
</directory>
- <directory name="moh" path="/opt/freeswitch/sounds/music/16000">
+ <directory name="mohh" path="/opt/freeswitch/sounds/music/16000">
<param name="rate" value="16000"/>
<param name="shuffle" value="true"/>
<param name="channels" value="1"/>
<param name="interval" value="20"/>
<param name="timer-name" value="soft"/>
</directory>
- <directory name="mohl" path="/opt/freeswitch/sounds/music/8000">
+ <directory name="moh" path="/opt/freeswitch/sounds/music/8000">
<param name="rate" value="8000"/>
<param name="shuffle" value="true"/>
<param name="channels" value="1"/>
@@ -541,30 +530,13 @@
</profile>
</profiles>
</configuration>
- <configuration name="xml_rpc.conf" description="XML RPC">
- <settings>
- <param name="http-port" value="228080"/>
- <param name="auth-realm" value="gemeinschaft"/>
- <param name="auth-user" value="7ff020f74d99a1b88bd2"/>
- <param name="auth-pass" value="85d13b5a56c55f7261cc"/>
- </settings>
- </configuration>
<configuration name="switch.conf" description="Core Configuration">
<cli-keybindings>
</cli-keybindings>
<settings>
- <param name="colorize-console" value="true"/>
- <param name="max-sessions" value="1000"/>
- <param name="sessions-per-second" value="30"/>
- <param name="loglevel" value="debug"/>
- <param name="mailer-app" value="sendmail"/>
- <param name="mailer-app-args" value="-t"/>
<param name="dump-cores" value="yes"/>
<param name="auto-create-schemas" value="true"/>
- <param name="rtp-enable-zrtp" value="false"/>
- <param name="rtp-start-port" value="16384" />
- <param name="rtp-end-port" value="32768" />
- <param name="core-db-dsn" value="gemeinschaft:gemeinschaft:gemeinschaft"/>
+ <param name="core-db-dsn" value="gemeinschaft:gemeinschaft:gemeinschaft"/>
</settings>
</configuration>
<configuration name="spandsp.conf" description="Tone detector descriptors">
@@ -635,8 +607,8 @@
<param name="verbose" value="true"/>
<param name="disable-v17" value="false"/>
<param name="ident" value=""/>
- <param name="header" value="GS4"/>
- <param name="spool-dir" value="/opt/GS5/misc/fax"/>
+ <param name="header" value="Gemeinschaft"/>
+ <param name="spool-dir" value="/var/spool/freeswitch"/>
<param name="file-prefix" value="fax_in_"/>
</settings>
</configuration>
@@ -645,8 +617,6 @@
<load module="mod_console"/>
<load module="mod_logfile"/>
<load module="mod_lua"/>
- <!-- <load module="mod_xml_rpc"/> -->
- <!-- <load module="mod_cdr_csv"/> -->
<load module="mod_event_socket"/>
<load module="mod_sofia"/>
<load module="mod_loopback"/>
@@ -654,12 +624,8 @@
<load module="mod_conference"/>
<load module="mod_dptools"/>
<load module="mod_expr"/>
- <!-- <load module="mod_fifo"/> -->
<load module="mod_voicemail"/>
- <!-- <load module="mod_esf"/> -->
- <!-- <load module="mod_fsv"/> -->
<load module="mod_valet_parking"/>
- <!-- <load module="mod_curl"/> -->
<load module="mod_dialplan_xml"/>
<load module="mod_sndfile"/>
<load module="mod_native_file"/>
@@ -668,63 +634,7 @@
<load module="mod_say_en"/>
<load module="mod_spandsp"/>
</modules>
- </configuration>
- <configuration name="post_load_modules.conf" description="Modules">
- <modules>
- </modules>
- </configuration>
- <configuration name="voicemail.conf" description="Voicemail">
- <settings>
- </settings>
- <profiles>
- <profile name="default">
- <param name="file-extension" value="wav"/>
- <param name="terminator-key" value="#"/>
- <param name="max-login-attempts" value="3"/>
- <param name="digit-timeout" value="10000"/>
- <param name="min-record-len" value="3"/>
- <param name="max-record-len" value="300"/>
- <param name="max-retries" value="3"/>
- <param name="tone-spec" value="%(1000, 0, 640)"/>
- <param name="callback-dialplan" value="XML"/>
- <param name="callback-context" value="default"/>
- <param name="play-new-messages-key" value="1"/>
- <param name="play-saved-messages-key" value="2"/>
- <param name="login-keys" value="0"/>
- <param name="main-menu-key" value="0"/>
- <param name="config-menu-key" value="5"/>
- <param name="record-greeting-key" value="1"/>
- <param name="choose-greeting-key" value="2"/>
- <param name="change-pass-key" value="6"/>
- <param name="record-name-key" value="3"/>
- <param name="record-file-key" value="3"/>
- <param name="listen-file-key" value="1"/>
- <param name="save-file-key" value="2"/>
- <param name="delete-file-key" value="7"/>
- <param name="undelete-file-key" value="8"/>
- <param name="email-key" value="4"/>
- <param name="pause-key" value="0"/>
- <param name="restart-key" value="1"/>
- <param name="ff-key" value="6"/>
- <param name="rew-key" value="4"/>
- <param name="skip-greet-key" value="#"/>
- <param name="record-silence-threshold" value="200"/>
- <param name="record-silence-hits" value="2"/>
- <param name="web-template-file" value="web-vm.tpl"/>
- <param name="operator-extension" value="operator XML default"/>
- <param name="operator-key" value="9"/>
- <param name="vmain-extension" value="vmain XML default"/>
- <param name="vmain-key" value="*"/>
- <param name="odbc-dsn" value="gemeinschaft:gemeinschaft:gemeinschaft"/>
- <email>
- <param name="notify-template-file" value="notify-voicemail.tpl"/>
- <param name="template-file" value="voicemail.tpl"/>
- <param name="date-fmt" value="%A, %B %d %Y, %I %M %p"/>
- <param name="email-from" value="${voicemail_account}@${voicemail_domain}"/>
- </email>
- </profile>
- </profiles>
- </configuration>
+ </configuration>
<configuration name="lua.conf" description="LUA Configuration">
<settings>
<param name="script-directory" value="$${base_dir}/scripts/?.lua"/>
diff --git a/misc/freeswitch/scripts/acd_wait.lua b/misc/freeswitch/scripts/acd_wait.lua
index fd16bea..c05cc24 100644
--- a/misc/freeswitch/scripts/acd_wait.lua
+++ b/misc/freeswitch/scripts/acd_wait.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5: acd call handler
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
local caller_uuid = argv[1];
diff --git a/misc/freeswitch/scripts/common/call_forwarding.lua b/misc/freeswitch/scripts/common/call_forwarding.lua
index 3942d05..400fcde 100644
--- a/misc/freeswitch/scripts/common/call_forwarding.lua
+++ b/misc/freeswitch/scripts/common/call_forwarding.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: call forwarding class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/call_history.lua b/misc/freeswitch/scripts/common/call_history.lua
index 7a9ac07..7e1e22b 100644
--- a/misc/freeswitch/scripts/common/call_history.lua
+++ b/misc/freeswitch/scripts/common/call_history.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: call_history class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/conference.lua b/misc/freeswitch/scripts/common/conference.lua
index d2bf829..ca5fa62 100644
--- a/misc/freeswitch/scripts/common/conference.lua
+++ b/misc/freeswitch/scripts/common/conference.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: conference class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -103,8 +103,9 @@ function Conference.enter(self, caller, domain)
end;
end
+ require 'common.str'
-- Check if conference is within time frame
- if self.record.start and self.record['end'] then
+ if not common.str.blank(self.record.start) and not common.str.blank(self.record['end']) then
local d = {}
_,_,d.year,d.month,d.day,d.hour,d.min,d.sec=string.find(self.record.start, "(%d+)-(%d+)-(%d+) (%d+):(%d+):(%d+)");
@@ -122,7 +123,6 @@ function Conference.enter(self, caller, domain)
end
end
- require 'common.str'
-- Owner ist always moderator
if (tonumber(self.record.conferenceable_id) == caller.account_owner_id) and (self.record.conferenceable_type == caller.account_owner_type) then
table.insert(flags, 'moderator');
diff --git a/misc/freeswitch/scripts/common/configuration_file.lua b/misc/freeswitch/scripts/common/configuration_file.lua
index 67e1f3b..3b3efbc 100644
--- a/misc/freeswitch/scripts/common/configuration_file.lua
+++ b/misc/freeswitch/scripts/common/configuration_file.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: configuration file
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/configuration_table.lua b/misc/freeswitch/scripts/common/configuration_table.lua
new file mode 100644
index 0000000..85bc014
--- /dev/null
+++ b/misc/freeswitch/scripts/common/configuration_table.lua
@@ -0,0 +1,46 @@
+-- Gemeinschaft 5 module: configuration table
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+-- retrieve configuration from database
+function get(database, entity, section)
+ if not database or not entity then
+ return {};
+ end
+
+ require 'common.str'
+
+ local sql_query = 'SELECT * FROM `gs_parameters` WHERE `entity` = "' .. entity .. '"';
+ if section then
+ sql_query = sql_query .. ' AND `section` = "' .. section .. '"';
+ end
+
+ local root = {}
+ local parameter_class = '';
+
+ database:query(sql_query, function(parameters)
+ local p_section = common.str.strip(parameters.section):lower();
+ local p_class_type = common.str.strip(parameters.class_type):lower();
+ local p_name = common.str.strip(parameters.name);
+
+ if not root[p_section] then
+ root[p_section] = {};
+ end
+
+ if p_class_type == 'boolean' then
+ root[p_section][p_name] = common.str.to_b(parameters.value);
+ elseif p_class_type == 'integer' then
+ root[p_section][p_name] = common.str.to_i(parameters.value);
+ else
+ root[p_section][p_name] = tostring(parameters.value);
+ end
+ end)
+
+ if section then
+ return root[section];
+ end
+
+ return root;
+end
diff --git a/misc/freeswitch/scripts/common/database.lua b/misc/freeswitch/scripts/common/database.lua
index 3692f84..1f39135 100644
--- a/misc/freeswitch/scripts/common/database.lua
+++ b/misc/freeswitch/scripts/common/database.lua
@@ -1,12 +1,12 @@
-- Gemeinschaft 5 module: database class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2013
--
module(...,package.seeall)
Database = {}
-DATABASE_DRIVER = 'mysql'
+DATABASE_DSN = 'gemeinschaft';
function Database.new(self, arg)
arg = arg or {}
@@ -20,117 +20,49 @@ function Database.new(self, arg)
end
-function Database.connect(self, database_name, user_name, password, host_name)
- local database_driver = nil;
- if not (database_name and user_name and password) then
- require 'common.configuration_file'
- local config = common.configuration_file.get('/opt/freeswitch/scripts/ini/database.ini');
- if config then
- database_driver = config[true].driver
- database_name = config[database_driver].database
- user_name = config[database_driver].user
- password = config[database_driver].password
- host_name = config[database_driver].host
- end
- end
+function Database.connect(self)
+ self.dsn = DATABASE_DSN;
- host_name = host_name or 'localhost';
- database_driver = database_driver or DATABASE_DRIVER;
+ require 'common.configuration_file'
+ local dsn = common.configuration_file.get('/var/lib/freeswitch/.odbc.ini', self.dsn);
- if database_driver == 'mysql' then
- require "luasql.mysql"
- self.env = luasql.mysql();
- elseif database_driver == 'odbc' then
- require "luasql.odbc"
- self.env = luasql.odbc();
- end
+ self.database_name = dsn.DATABASE;
+ self.user_name = dsn.USER;
+ self.password = dsn.PASSWORD;
+ self.host_name = dsn.HOST;
- self.conn = self.env:connect(database_name, user_name, password, host_name);
+ self.conn = freeswitch.Dbh(self.dsn, self.user_name, self.password);
self.conn_id = tostring(self.conn);
- self.database_name = database_name;
- self.user_name = user_name;
- self.password = password;
- self.host_name = host_name;
-
- -- self.log:debug('DATABASE_CONNECT - connection: ', self.conn_id, ', environment: ', self.env);
-
- return self;
-end
-
-
-function Database.reconnect(self)
- self.conn = self.env:connect(self.database_name, self.user_name, self.password, self.host_name);
- self.conn_id = tostring(self.conn);
-
- if self.log then
- self.log:info('DATABASE_RECONNECT - connection: ', self.conn_id, ', environment: ', self.env);
- end
return self;
end
function Database.connected(self)
- return self.conn;
+ return self.conn:connected();
end
function Database.query(self, sql_query, call_function)
- local cursor = self.conn:execute(sql_query);
-
- if cursor == nil and not self.conn:execute('SELECT @@VERSION') then
- if self.log then
- self.log:error('DATABASE_QUERY - lost connection: ', self.conn_id, ', environment: ', self.env, ', query: ', sql_query);
- end
- self:reconnect();
-
- if call_function then
- cursor = self.conn:execute(sql_query);
- self.log:notice('DATABASE_QUERY - retry: ', sql_query);
- end
- end
-
- if cursor and call_function then
- repeat
- row = cursor:fetch({}, 'a');
- if row then
- call_function(row);
- end
- until not row;
+ if call_function then
+ return self.conn:query(sql_query, call_function);
+ else
+ return self.conn:query(sql_query);
end
-
- if type(cursor) == 'userdata' then
- cursor:close();
- end
-
- return cursor;
end
function Database.query_return_value(self, sql_query)
- local cursor = self.conn:execute(sql_query);
+ local result = nil;
- if cursor == nil and not self.conn:execute('SELECT @@VERSION') then
- if self.log then
- self.log:error('DATABASE_QUERY - lost connection: ', self.conn_id, ', environment: ', self.env, ', query: ', sql_query);
+ self.conn:query(sql_query, function(row)
+ for key, value in pairs(row) do
+ result = value;
+ return result;
end
- self:reconnect();
- cursor = self.conn:execute(sql_query);
- self.log:notice('DATABASE_QUERY - retry: ', sql_query);
- end
-
- if type(cursor) == 'userdata' then
- local row = cursor:fetch({}, 'n');
- cursor:close();
-
- if not row then
- return row;
- else
- return row[1];
- end
- end
+ end)
- return cursor;
+ return result;
end
@@ -139,13 +71,8 @@ function Database.last_insert_id(self)
end
-function Database.release(self, sql_query, call_function)
+function Database.release(self)
if self.conn then
- self.conn:close();
- end
- if self.env then
- self.env:close();
+ self.conn:release();
end
-
- -- self.log:debug('DATABASE_RELEASE - connection: ', self.conn_id, ', status: ', self.env, ', ', self.conn);
end
diff --git a/misc/freeswitch/scripts/common/fapi.lua b/misc/freeswitch/scripts/common/fapi.lua
index 0a05155..5b96633 100644
--- a/misc/freeswitch/scripts/common/fapi.lua
+++ b/misc/freeswitch/scripts/common/fapi.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: FS api class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/gateway.lua b/misc/freeswitch/scripts/common/gateway.lua
new file mode 100644
index 0000000..e50c763
--- /dev/null
+++ b/misc/freeswitch/scripts/common/gateway.lua
@@ -0,0 +1,168 @@
+-- Gemeinschaft 5 module: gateway class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Gateway = {}
+
+-- Create Gateway object
+function Gateway.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'gateway';
+ self.log = arg.log;
+ self.database = arg.database;
+ self.record = arg.record;
+ self.GATEWAY_PREFIX = 'gateway';
+ return object;
+end
+
+
+function Gateway.list(self, technology)
+ technology = technology or 'sip';
+ local sql_query = 'SELECT * FROM `gateways` WHERE (`outbound` IS TRUE OR `inbound` IS TRUE) AND `technology` = "' .. technology .. '"';
+ local gateways = {};
+ self.database:query(sql_query, function(entry)
+ table.insert(gateways, entry);
+ end)
+
+ return gateways;
+end
+
+
+function Gateway.find_by_id(self, id)
+ local sql_query = 'SELECT * FROM `gateways` WHERE `id`= ' .. tonumber(id) .. ' LIMIT 1';
+
+ local gateway = nil;
+ self.database:query(sql_query, function(entry)
+ gateway = Gateway:new(self);
+ gateway.record = entry;
+ gateway.id = tonumber(entry.id);
+ gateway.name = entry.name;
+ end)
+
+ if gateway then
+ gateway.settings = self:config_table_get('gateway_settings', gateway.id);
+ end
+
+ return gateway;
+end
+
+
+function Gateway.find_by_name(self, name)
+ local gateway_name = name:gsub('([^%a%d%._%+])', '');
+
+ local sql_query = 'SELECT * FROM `gateways` WHERE `name`= "' .. gateway_name .. '" LIMIT 1';
+
+ local gateway = nil;
+ self.database:query(sql_query, function(entry)
+ gateway = Gateway:new(self);
+ gateway.record = entry;
+ gateway.id = tonumber(entry.id);
+ gateway.name = entry.name;
+ end)
+
+ if gateway then
+ gateway.settings = self:config_table_get('gateway_settings', gateway.id);
+ end
+
+ return gateway;
+end
+
+
+function Gateway.authenticate(self, technology, caller)
+ local sql_query = 'SELECT `c`.`name`, `c`.`id`, `a`.`value` `auth_source`, `b`.`value` `auth_pattern` \
+ FROM `gateway_settings` `a` \
+ INNER JOIN `gateway_settings` `b` \
+ ON (`a`.`gateway_id` = `b`.`gateway_id` AND `a`.`name` = "auth_source" AND `b`.`name` = "auth_pattern" ) \
+ LEFT JOIN `gateways` `c` \
+ ON (`a`.`gateway_id` = `c`.`id`) \
+ WHERE `c`.`inbound` IS TRUE AND `c`.`technology` = "' .. tostring(technology) .. '"';
+
+ local gateway = false;
+
+ self.database:query(sql_query, function(entry)
+ if caller:to_s(entry.auth_source):match(entry.auth_pattern) then
+ gateway = entry;
+ return;
+ end
+ end)
+
+ return gateway;
+end
+
+
+function Gateway.profile_get(self, gateway_id)
+ local sql_query = 'SELECT `value` FROM `gateway_settings` WHERE `gateway_id` = ' .. tonumber(gateway_id) .. ' AND `name` = "profile" LIMIT 1';
+
+ return self.database:query_return_value(sql_query);
+end
+
+
+function Gateway.config_table_get(self, config_table, gateway_id)
+ require 'common.str'
+
+ local sql_query = 'SELECT * FROM `'.. config_table ..'` WHERE `gateway_id` = ' .. tonumber(gateway_id);
+
+ local settings = {};
+ self.database:query(sql_query, function(entry)
+ local p_class_type = common.str.strip(entry.class_type):lower();
+ local p_name = common.str.strip(entry.name):lower();
+
+ if p_class_type == 'boolean' then
+ settings[p_name] = common.str.to_b(entry.value);
+ elseif p_class_type == 'integer' then
+ settings[p_name] = common.str.to_i(entry.value);
+ else
+ settings[p_name] = tostring(entry.value);
+ end
+ end)
+
+ return settings
+end
+
+
+function Gateway.parameters_build(self, gateway_id)
+ local settings = self:config_table_get('gateway_settings', gateway_id);
+ local parameters = {
+ realm = settings.domain,
+ extension = 'auto_to_user',
+ };
+
+ require 'common.str'
+
+ if common.str.blank(settings.username) then
+ parameters.username = 'gateway' .. gateway_id;
+ parameters.register = false;
+ else
+ parameters.username = settings.username;
+ parameters.register = true;
+ end
+
+ if not common.str.blank(settings.register) then
+ parameters.register = common.str.to_b(settings.register);
+ end
+
+ if common.str.blank(settings.password) then
+ parameters.password = 'gateway' .. gateway_id;
+ else
+ parameters.password = settings.password;
+ end
+
+ parameters['extension-in-contact'] = true;
+
+ if common.str.blank(settings.contact) then
+ parameters['extension'] = 'gateway' .. gateway_id;
+ else
+ parameters['extension'] = settings.contact;
+ end
+
+ for key, value in pairs(self:config_table_get('gateway_parameters', gateway_id)) do
+ parameters[key] = value;
+ end
+
+ return parameters;
+end
diff --git a/misc/freeswitch/scripts/common/ipcalc.lua b/misc/freeswitch/scripts/common/ipcalc.lua
index 5c19d20..49cb56c 100644
--- a/misc/freeswitch/scripts/common/ipcalc.lua
+++ b/misc/freeswitch/scripts/common/ipcalc.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: ip calculation functions
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/log.lua b/misc/freeswitch/scripts/common/log.lua
index d0d13dc..5aff2b8 100644
--- a/misc/freeswitch/scripts/common/log.lua
+++ b/misc/freeswitch/scripts/common/log.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: log
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/phone_number.lua b/misc/freeswitch/scripts/common/phone_number.lua
index 4df0d57..6635296 100644
--- a/misc/freeswitch/scripts/common/phone_number.lua
+++ b/misc/freeswitch/scripts/common/phone_number.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: phone number class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/routing_tables.lua b/misc/freeswitch/scripts/common/routing_tables.lua
deleted file mode 100644
index 34d0143..0000000
--- a/misc/freeswitch/scripts/common/routing_tables.lua
+++ /dev/null
@@ -1,66 +0,0 @@
--- Gemeinschaft 5 module: routing table functions
--- (c) AMOOMA GmbH 2012
---
-
-module(...,package.seeall)
-
-function expand_variables(line, variables_list)
- variables_list = variables_list or {};
-
- return (line:gsub('{([%a%d_]+)}', function(captured)
- return variables_list[captured] or '';
- end))
-end
-
-
-function match_route(entry, search_str, variables_list)
- if not entry or not search_str then
- return { error = 'No input values' };
- end
-
- local result = nil;
- local success = nil;
- success, result = pcall(string.find, search_str, entry[1]);
-
- if not success then
- return { error = result, line = line }
- elseif result then
- local route = {
- pattern = entry[1],
- value = search_str:gsub(entry[1], expand_variables(entry[#entry], variables_list)),
- }
-
- for index = 2, #entry-1 do
- local attribute = entry[index]:match('^(.-)%s*=');
- if attribute then
- route[attribute] = entry[index]:match('=%s*(.-)$');
- end
- end
-
- return route;
- end
-
- return {};
-end
-
-
-function match_caller_id(entry, search_str, variables_list)
- if not entry or not search_str then
- return { error = 'No input values' };
- end
- local result = nil;
- local success = nil;
- success, result = pcall(string.find, search_str, entry[1]);
- if not success then
- return { error = result, line = line }
- elseif result then
- return {
- value = search_str:gsub(entry[1], expand_variables(entry[4], variables_list)),
- class = entry[2],
- endpoint = entry[3],
- pattern = entry[1],
- }
- end
-
- return {};
-end
diff --git a/misc/freeswitch/scripts/common/sip_account.lua b/misc/freeswitch/scripts/common/sip_account.lua
index 28a00df..8dd432b 100644
--- a/misc/freeswitch/scripts/common/sip_account.lua
+++ b/misc/freeswitch/scripts/common/sip_account.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: sip account class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/common/str.lua b/misc/freeswitch/scripts/common/str.lua
index ca6dcd9..32f054e 100644
--- a/misc/freeswitch/scripts/common/str.lua
+++ b/misc/freeswitch/scripts/common/str.lua
@@ -1,27 +1,17 @@
-- Gemeinschaft 5 module: string functions
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
function try(array, arguments)
- local argument = arguments:match('^(.-)%.') or arguments;
- local remaining_arguments = arguments:match('%.(.-)$');
- argument = tonumber(argument) or argument;
+ local result = array;
- if argument and type(array) == 'table' then
- if remaining_arguments then
- if type(array[argument]) == 'table' then
- return try(array[argument], remaining_arguments);
- else
- return nil;
- end
- else
- return array[argument];
- end
- end
-
- return nil;
+ arguments:gsub('([^%.]+)', function(entry)
+ local success, result = pcall(function() result = (result[tonumber(entry) or entry]); end);
+ end);
+
+ return result;
end
-- to number
diff --git a/misc/freeswitch/scripts/common/sync_log.lua b/misc/freeswitch/scripts/common/sync_log.lua
index 05b0dcf..3fdb646 100644
--- a/misc/freeswitch/scripts/common/sync_log.lua
+++ b/misc/freeswitch/scripts/common/sync_log.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: sync log class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/configuration.lua b/misc/freeswitch/scripts/configuration.lua
index 906d3f8..9e62bb6 100644
--- a/misc/freeswitch/scripts/configuration.lua
+++ b/misc/freeswitch/scripts/configuration.lua
@@ -1,8 +1,11 @@
-- Gemeinschaft 5 dynamic freeswitch configuration
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
function nodes(database, local_node_id)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
local gateways_xml = '';
require 'common.node'
@@ -14,86 +17,162 @@ function nodes(database, local_node_id)
node_parameters['proxy'] = node_record.ip_address;
node_parameters['register'] = 'false';
log:debug('NODE_GATEWAY ', node_record.id, ' - name: ', node_record.name, ', address: ', node_record.ip_address);
- gateways_xml = gateways_xml .. xml:gateway(node_record.name, node_parameters);
+ gateways_xml = gateways_xml .. xml:element{
+ 'gateway',
+ name = node_record.name,
+ xml:from_hash('param', node_parameters, 'name', 'value'),
+ };
end
end
return gateways_xml;
end
-function gateways(profile_name)
- local gateways_xml = '';
- local gateways = common.configuration_file.get('/opt/freeswitch/scripts/ini/gateways.ini', false);
- if not gateways then
- return '';
- end
+function gateways(database, profile_name)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
+ require 'common.str'
- for sofia_gateway, gateway_parameters in pairs(gateways) do
- if tostring(gateway_parameters.profile) == profile_name then
- log:debug('GATEWAY - name: ', sofia_gateway, ', address: ', gateway_parameters.proxy);
- gateways_xml = gateways_xml .. xml:gateway(sofia_gateway, gateway_parameters);
+ require 'common.gateway'
+ local gateway_class = common.gateway.Gateway:new{ log = log, database = database};
+ local gateways = gateway_class:list('sip');
+
+ local gateways_xml = '';
+ for index=1, #gateways do
+ local gateway = gateways[index];
+ local gateway_profile = gateway_class:profile_get(gateway.id);
+ if tostring(gateway_profile) == profile_name or (profile_name == 'gemeinschaft' and common.str.blank(gateway_profile)) then
+ log:debug('GATEWAY - name: ', gateway.name);
+ local parameters = gateway_class:parameters_build(gateway.id);
+
+ gateways_xml = gateways_xml .. xml:element{
+ 'gateway',
+ name = gateway_class.GATEWAY_PREFIX .. gateway.id,
+ xml:from_hash('param', parameters, 'name', 'value'),
+ };
end
end
return gateways_xml;
end
+
function profile(database, sofia_ini, profile_name, index, domains, node_id)
- local profile_parameters = sofia_ini['profile:' .. profile_name];
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
+ local parameters = sofia_ini['profile:' .. profile_name];
- if not profile_parameters then
+ if not parameters then
log:error('SOFIA_PROFILE ', index,' - name: ', profile_name, ' - no parameters');
return '';
end
+
+ if tostring(parameters['odbc-dsn']) == 'default' then
+ parameters['odbc-dsn'] = 'gemeinschaft:' .. tostring(database.user_name) .. ':' .. tostring(database.password);
+ end
+
-- set local bind address
if domains[index] then
- profile_parameters['sip-ip'] = domains[index]['host'];
- profile_parameters['rtp-ip'] = domains[index]['host'];
- profile_parameters['force-register-domain'] = domains[index]['host'];
- profile_parameters['force-subscription-domain'] = domains[index]['host'];
- profile_parameters['force-register-db-domain'] = domains[index]['host'];
- log:debug('SOFIA_PROFILE ', index,' - name: ', profile_name, ', domain: ', domains[index]['host'], ', sip_bind: ', profile_parameters['sip-ip'], ':', profile_parameters['sip-port']);
+ parameters['sip-ip'] = domains[index]['host'];
+ parameters['rtp-ip'] = domains[index]['host'];
+ parameters['force-register-domain'] = domains[index]['host'];
+ parameters['force-subscription-domain'] = domains[index]['host'];
+ parameters['force-register-db-domain'] = domains[index]['host'];
+ log:debug('SOFIA_PROFILE ', index,' - name: ', profile_name, ', domain: ', domains[index]['host'], ', sip_bind: ', parameters['sip-ip'], ':', parameters['sip-port']);
else
- log:error('SOFIA_PROFILE ', index,' - name: ', profile_name, ' - no domains');
+ log:debug('SOFIA_PROFILE ', index,' - name: ', profile_name, ' - no domains');
end
- local gateways_xml = gateways(profile_name);
+ local gateways_xml = gateways(database, profile_name);
if index == 1 then
gateways_xml = gateways_xml .. nodes(database, node_id);
end
- return xml:sofia_profile(profile_name, profile_parameters, gateways_xml);
+ local profile_xml = xml:element{
+ 'profile',
+ name = profile_name,
+ xml:element{
+ 'gateways',
+ gateways_xml,
+ },
+ xml:element{
+ 'domains',
+ xml:element{
+ 'domain',
+ name = 'all',
+ alias = 'true',
+ parse = 'false',
+ },
+ },
+ xml:element{
+ 'settings',
+ xml:from_hash('param', parameters, 'name', 'value'),
+ },
+ };
+
+ return profile_xml;
end
+
-- generate sofia.conf
function conf_sofia(database)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
+ require 'common.configuration_table'
local sofia_profile = "gemeinschaft";
- require 'common.configuration_file'
- local sofia_ini = common.configuration_file.get('/opt/freeswitch/scripts/ini/sofia.ini');
- local dialplan_parameters = common.configuration_file.get('/opt/freeswitch/scripts/ini/dialplan.ini', 'parameters');
+ local sofia_ini = common.configuration_table.get(database, 'sofia');
+ local dialplan_parameters = common.configuration_table.get(database, 'dialplan', 'parameters');
- local local_node_id = tonumber(dialplan_parameters['node_id']) or 1;
+ local local_node_id = tonumber(dialplan_parameters.node_id) or 1;
require 'configuration.sip'
local domains = configuration.sip.Sip:new{ log = log, database = database}:domains();
sofia_profiles_xml = '';
- for index, profile_name in ipairs(sofia_ini.profiles) do
- sofia_profiles_xml = sofia_profiles_xml .. profile(database, sofia_ini, profile_name, index, domains, local_node_id);
+ for profile_name, index in pairs(sofia_ini.profiles) do
+ if tonumber(index) and tonumber(index) > 0 then
+ sofia_profiles_xml = sofia_profiles_xml .. profile(database, sofia_ini, profile_name, tonumber(index), domains, local_node_id);
+ end
end
- XML_STRING = xml:document(xml:sofia(sofia_ini.parameters, sofia_profiles_xml))
+ XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+ xml:element{
+ 'section',
+ name = 'configuration',
+ description = 'Gemeinschaft 5 FreeSWITCH configuration',
+ xml:element{
+ 'configuration',
+ name = 'sofia.conf',
+ description = 'Sofia configuration',
+ xml:element{
+ 'global_settings',
+ xml:from_hash('param', sofia_ini.parameters, 'name', 'value'),
+ },
+ xml:element{
+ 'profiles',
+ sofia_profiles_xml,
+ },
+ },
+ },
+ };
+
end
function conf_conference(database)
- XML_STRING = xml:document(xml:conference());
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
- require 'common.configuration_file'
- local conference_ini = common.configuration_file.get('/opt/freeswitch/scripts/ini/conferences.ini');
- local conference_parameters = conference_ini.parameters;
+ require 'common.configuration_table'
+ local config = common.configuration_table.get(database, 'conferences');
+ local profiles = nil;
local event_name = params:getHeader("Event-Name")
if event_name == 'COMMAND' then
@@ -105,8 +184,15 @@ function conf_conference(database)
conference = common.conference.Conference:new{log=log, database=database}:find_by_id(conf_name);
if conference then
log:debug('CONFIG_CONFERENCE ', conf_name, ' name: ', conference.record.name, ', profile: ', profile_name);
- conference_parameters['caller-id-name'] = conference.record.name or '';
- XML_STRING = xml:document(xml:conference(xml:conference_profile(profile_name, conference_parameters)));
+ config.parameters['caller-id-name'] = conference.record.name or '';
+ profiles = xml:element{
+ 'profiles',
+ xml:element{
+ 'profile',
+ name = profile_name,
+ xml:from_hash('param', config.parameters, 'name', 'value'),
+ },
+ };
else
log:error('CONFIG_CONFERENCE ', conf_name, ' - conference not found');
end
@@ -116,61 +202,251 @@ function conf_conference(database)
else
log:debug('CONFIG_CONFERENCE ', conf_name, ' - event: ', event_name);
end
+
+ XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+ xml:element{
+ 'section',
+ name = 'configuration',
+ description = 'Gemeinschaft 5 FreeSWITCH configuration',
+ xml:element{
+ 'configuration',
+ name = 'conference.conf',
+ description = 'Conference configuration',
+ xml:element{
+ 'caller-controls',
+ xml:element{
+ 'group',
+ name = 'speaker',
+ xml:from_hash('control', config.controls_speaker, 'action', 'digits'),
+ },
+ xml:element{
+ 'group',
+ name = 'moderator',
+ xml:from_hash('control', config.controls_moderator, 'action', 'digits'),
+ },
+ },
+ profiles,
+ },
+ },
+ };
+end
+
+function conf_voicemail(database)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
+ require 'common.configuration_table';
+ local parameters = common.configuration_table.get(database, 'voicemail', 'parameters');
+
+ if tostring(parameters['odbc-dsn']) == 'default' then
+ parameters['odbc-dsn'] = 'gemeinschaft:' .. tostring(database.user_name) .. ':' .. tostring(database.password);
+ end
+
+ XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+ xml:element{
+ 'section',
+ name = 'configuration',
+ description = 'Gemeinschaft 5 FreeSWITCH configuration',
+ xml:element{
+ 'configuration',
+ name = 'voicemail.conf',
+ description = 'Voicemail configuration',
+ xml:element{
+ 'profiles',
+ xml:element{
+ 'profile',
+ name = 'default',
+ xml:from_hash('param', parameters, 'name', 'value'),
+ },
+ },
+ },
+ },
+ };
+end
+
+function conf_post_switch(database)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
+ require 'common.configuration_table';
+ local parameters = common.configuration_table.get(database, 'post_load_switch', 'settings');
+
+ XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+ xml:element{
+ 'section',
+ name = 'configuration',
+ description = 'Gemeinschaft 5 FreeSWITCH configuration',
+ xml:element{
+ 'configuration',
+ name = 'post_load_switch.conf',
+ description = 'Switch configuration',
+ xml:element{
+ 'settings',
+ xml:from_hash('param', parameters, 'name', 'value'),
+ },
+ },
+ },
+ };
end
function directory_sip_account(database)
+ require 'configuration.simple_xml'
+ local xml = configuration.simple_xml.SimpleXml:new();
+
local key = params:getHeader('key');
local auth_name = params:getHeader('user');
local domain = params:getHeader('domain');
local purpose = params:getHeader('purpose');
+ local user_xml = nil;
+
if auth_name and auth_name ~= '' then
-- sip account or gateway
if string.len(auth_name) > 3 and auth_name:sub(1, 3) == 'gw+' then
local gateway_name = auth_name:sub(4);
domain = domain or freeswitch.API():execute('global_getvar', 'domain');
- require 'configuration.sip'
- log:notice('DATABASE: ', database);
- local sip_gateway = configuration.sip.Sip:new{ log = log, database = database}:find_gateway_by_name(gateway_name);
- if sip_gateway ~= nil and next(sip_gateway) ~= nil then
+ require 'common.gateway'
+ local sip_gateway = common.gateway.Gateway:new{ log = self.log, database = self.database }:find_by_name(gateway_name);
+ if sip_gateway then
log:debug('DIRECTORY_GATEWAY - name: ', gateway_name, ', auth_name: ', auth_name);
- XML_STRING = xml:document(xml:directory(xml:gateway_user(sip_gateway, gateway_name, auth_name), domain));
+
+ local user_variables = {
+ user_context = "default",
+ gs_from_gateway = "true",
+ gs_gateway_name = gateway_name,
+ gs_gateway_id = sip_gateway.id,
+ }
+
+ user_xml = xml:element{
+ 'user',
+ id = auth_name,
+ xml:element{
+ 'params',
+ xml:element{
+ 'param',
+ password = sip_gateway.record.password,
+ }
+ },
+ xml:element{
+ 'variables',
+ xml:from_hash('variable', user_variables, 'name', 'value'),
+ },
+ };
else
log:debug('DIRECTORY_GATEWAY - gateway not found - name: ', gateway_name, ', auth_name: ', auth_name);
end
else
require 'common.sip_account'
local sip_account = common.sip_account.SipAccount:new{ log = log, database = database}:find_by_auth_name(auth_name, domain);
+
+ require 'common.configuration_table'
+ local user_parameters = common.configuration_table.get(database, 'sip_accounts', 'parameters');
+
if sip_account ~= nil then
+ user_parameters['password'] = sip_account.record.password;
+ user_parameters['vm-password'] = sip_account.record.voicemail_pin;
+
+ local user_variables = {
+ user_context = "default",
+ gs_from_gateway = "false",
+ gs_account_id = sip_account.record.id,
+ gs_account_uuid = sip_account.record.uuid,
+ gs_account_type = "SipAccount",
+ gs_account_state = sip_account.record.state,
+ gs_account_caller_name = sip_account.record.caller_name,
+ gs_account_owner_type = sip_account.record.sip_accountable_type,
+ gs_account_owner_id = sip_account.record.sip_accountable_id
+ }
+
if tostring(purpose) == 'publish-vm' then
log:debug('DIRECTORY_SIP_ACCOUNT - purpose: VoiceMail, auth_name: ', sip_account.record.auth_name, ', caller_name: ', sip_account.record.caller_name, ', domain: ', domain);
- XML_STRING = xml:document(xml:directory(xml:group_default(xml:user(sip_account.record)), domain));
+ user_xml = xml:element{
+ 'groups',
+ xml:element{
+ 'group',
+ name = 'default',
+ xml:element{
+ 'users',
+ xml:element{
+ 'user',
+ id = sip_account.record.auth_name,
+ xml:element{
+ 'params',
+ xml:from_hash('param', user_parameters, 'name', 'value'),
+ },
+ xml:element{
+ 'variables',
+ xml:from_hash('variable', user_variables, 'name', 'value'),
+ },
+ },
+ },
+ },
+ };
else
log:debug('DIRECTORY_SIP_ACCOUNT - auth_name: ', sip_account.record.auth_name, ', caller_name: ', sip_account.record.caller_name, ', domain: ', domain);
- XML_STRING = xml:document(xml:directory(xml:user(sip_account.record), domain));
+
+ user_xml = xml:element{
+ 'user',
+ id = sip_account.record.auth_name,
+ xml:element{
+ 'params',
+ xml:from_hash('param', user_parameters, 'name', 'value'),
+ },
+ xml:element{
+ 'variables',
+ xml:from_hash('variable', user_variables, 'name', 'value'),
+ },
+ };
end
else
log:debug('DIRECTORY_SIP_ACCOUNT - sip account not found - auth_name: ', auth_name, ', domain: ', domain);
-- fake sip_account configuration
- sip_account = {
- auth_name = auth_name,
- id = 0,
- uuid = '',
- password = tostring(math.random(0, 65534)),
- voicemail_pin = '',
- state = 'inactive',
- caller_name = '',
- sip_accountable_type = 'none',
- sip_accountable_id = 0,
- }
- XML_STRING = xml:document(xml:directory(xml:user(sip_account), domain))
+ user_parameters['password'] = tostring(math.random(0, 65534));
+ user_parameters['vm-password'] = '';
+
+ user_xml = xml:element{
+ 'user',
+ id = auth_name,
+ xml:element{
+ 'params',
+ xml:from_hash('param', user_parameters, 'name', 'value'),
+ },
+ };
end
end
elseif tostring(XML_REQUEST.key_name) == 'name' and tostring(XML_REQUEST.key_value) ~= '' then
log:debug('DOMAIN_DIRECTORY - domain: ', XML_REQUEST.key_value);
XML_STRING = xml:document(xml:directory(nil, XML_REQUEST.key_value));
end
+
+ XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+ xml:element{
+ 'section',
+ name = 'directory',
+ xml:element{
+ 'domain',
+ name = domain,
+ xml:element{
+ 'params',
+ xml:element{
+ 'param',
+ name = 'dial-string',
+ value = '${sofia_contact(${dialed_user}@${dialed_domain})}',
+ },
+ },
+ user_xml,
+ },
+ },
+ };
end
@@ -182,9 +458,12 @@ log = common.log.Log:new();
log.prefix = '#C# [' .. log_identifier .. '] ';
-- return a valid xml document
-require 'configuration.freeswitch_xml'
-xml = configuration.freeswitch_xml.FreeSwitchXml:new();
-XML_STRING = xml:document();
+require 'configuration.simple_xml'
+local xml = configuration.simple_xml.SimpleXml:new();
+XML_STRING = xml:element{
+ 'document',
+ ['type'] = 'freeswitch/xml',
+};
local database = nil;
@@ -203,6 +482,10 @@ if XML_REQUEST.section == 'configuration' and XML_REQUEST.tag_name == 'configura
conf_sofia(database);
elseif XML_REQUEST.key_value == "conference.conf" then
conf_conference(database);
+ elseif XML_REQUEST.key_value == "voicemail.conf" then
+ conf_voicemail(database);
+ elseif XML_REQUEST.key_value == "post_load_switch.conf" then
+ conf_post_switch(database);
end
elseif XML_REQUEST.section == 'directory' and XML_REQUEST.tag_name == '' then
log:debug('SIP_ACCOUNT_DIRECTORY - initialization phase');
diff --git a/misc/freeswitch/scripts/configuration/freeswitch_xml.lua b/misc/freeswitch/scripts/configuration/freeswitch_xml.lua
deleted file mode 100644
index c81bf50..0000000
--- a/misc/freeswitch/scripts/configuration/freeswitch_xml.lua
+++ /dev/null
@@ -1,307 +0,0 @@
--- ConfigurationModule: FreeSwitchXml
---
-module(...,package.seeall)
-
-FreeSwitchXml = {}
-
--- Create FreeSwitchXml object
-function FreeSwitchXml.new(self, object)
- object = object or {}
- setmetatable(object, self)
- self.__index = self
- return object
-end
-
-function FreeSwitchXml.param(self, name, value)
- return '<param name="' .. name .. '" value="' .. value .. '"/>'
-end
-
-function FreeSwitchXml.variable(self, name, value)
- return '<variable name="' .. name .. '" value="' .. value .. '"/>'
-end
-
-function FreeSwitchXml.document(self, sections_xml)
- if type(sections_xml) == "string" then
- sections_xml = { sections_xml }
- elseif type(sections_xml) == "nil" then
- sections_xml = { "" }
- end
-
- local xml_string=
-[[<?xml version="1.0" encoding="UTF-8" standalone="no"?>
-<document type="freeswitch/xml">
-]] .. table.concat(sections_xml, "\n") .. [[
-
-</document>]]
-
- return xml_string
-end
-
-function FreeSwitchXml.directory(self, entries_xml, domain)
- if type(entries_xml) == "string" then
- entries_xml = { entries_xml }
- elseif type(entries_xml) == "nil" then
- entries_xml = { "" }
- end
-
- local xml_string =
-[[
-<section name="directory">
-<domain name="]] .. domain .. [[">
-<params>
-<param name="dial-string" value="${sofia_contact(${dialed_user}@${dialed_domain})}"/>
-</params>
-]] .. table.concat(entries_xml, "\n") .. [[
-
-</domain>
-</section>]]
- return xml_string
-end
-
-function FreeSwitchXml.group_default(self, entries_xml)
- if type(entries_xml) == "string" then
- entries_xml = { entries_xml }
- elseif type(entries_xml) == "nil" then
- entries_xml = { "" }
- end
-
- local xml_string =
-[[
-<groups>
-<group name="default">
-<users>
-]] .. table.concat(entries_xml, "\n") .. [[
-
-</users>
-</group>
-</groups>]]
- return xml_string
-end
-
-function FreeSwitchXml.user(self, user)
- require 'common.configuration_file'
- local params = common.configuration_file.get('/opt/freeswitch/scripts/ini/sip_accounts.ini', 'parameters');
-
- params['password'] = user.password;
- params['vm-password'] = user.voicemail_pin;
-
- local variables = {
- user_context = "default",
- gs_from_gateway = "false",
- gs_account_id = user.id,
- gs_account_uuid = user.uuid,
- gs_account_type = "SipAccount",
- gs_account_state = user.state,
- gs_account_caller_name = user.caller_name,
- gs_account_owner_type = user.sip_accountable_type,
- gs_account_owner_id = user.sip_accountable_id
- }
-
- local params_xml = {}
- for name, value in pairs(params) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
-
- local variables_xml = {}
- for name, value in pairs(variables) do
- variables_xml[#variables_xml+1] = self:variable(name, value)
- end
-
- local xml_string =
-[[
-<user id="]] .. user.auth_name .. [[">
-<params>
-]] .. table.concat(params_xml, "\n") .. [[
-
-</params>
-<variables>
-]] .. table.concat(variables_xml, "\n") .. [[
-
-</variables>
-</user>]]
- return xml_string
-end
-
-function FreeSwitchXml.gateway_user(self, user, gateway_name, auth_name)
- user.id = user.id or 0
-
- local params = {
- ['password'] = user.password,
- }
-
- local variables = {
- user_context = "default",
- gs_from_gateway = "true",
- gs_gateway_name = gateway_name,
- gs_gateway_id = user.id
- }
-
- local params_xml = {}
- for name, value in pairs(params) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
-
- local variables_xml = {}
- for name, value in pairs(variables) do
- variables_xml[#variables_xml+1] = self:variable(name, value)
- end
-
- local xml_string =
-[[
-<user id="]] .. auth_name .. [[">
-<params>
-]] .. table.concat(params_xml, "\n") .. [[
-
-</params>
-<variables>
-]] .. table.concat(variables_xml, "\n") .. [[
-
-</variables>
-</user>]]
- return xml_string
-end
-
-function FreeSwitchXml.sofia(self, parameters, profiles_xml)
- if type(profiles_xml) == "string" then
- profiles_xml = { profiles_xml }
- elseif type(profiles_xml) == "nil" then
- profiles_xml = { "" }
- end
-
- local params_xml = {}
- for name, value in pairs(parameters) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
-
- local xml_string =
-[[
-<section name="configuration" description="FreeSwitch configuration for Sofia Profile">
-<configuration name="sofia.conf" description="Sofia SIP Configuration">
-<global_settings>
-]] .. table.concat(params_xml, "\n") .. [[
-
-</global_settings>
-<profiles>
-]] .. table.concat(profiles_xml, "\n") .. [[
-
-</profiles>
-</configuration>
-</section>]]
- return xml_string
-end
-
-function FreeSwitchXml.sofia_profile(self, profile_name, parameters, gateways_xml)
- params_xml = {}
- for name, value in pairs(parameters) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
-
- if type(gateways_xml) == "string" then
- gateways_xml = { gateways_xml }
- elseif type(gateways_xml) == "nil" then
- gateways_xml = { "" }
- end
-
- local xml_string =
-[[
-<profile name="]] .. profile_name .. [[">
-<aliases>
-</aliases>
-<gateways>
-]] .. table.concat(gateways_xml, "\n") .. [[
-
-</gateways>
-<domains>
-<domain name="all" alias="true" parse="false"/>
-</domains>
-<settings>
-]] .. table.concat(params_xml, "\n") .. [[
-
-</settings>
-</profile>]]
- return xml_string
-end
-
-function FreeSwitchXml.gateway(self, gateway_name, parameters)
- local params_xml = {}
- if parameters then
- for name, value in pairs(parameters) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
- end
-
- local xml_string =
-[[
-<gateway name="]] .. gateway_name .. [[">
-]] .. table.concat(params_xml, "\n") .. [[
-
-</gateway>]]
- return xml_string
-end
-
-function FreeSwitchXml.conference(self, profiles_xml)
- if type(profiles_xml) == "string" then
- profiles_xml = { profiles_xml }
- elseif type(profiles_xml) == "nil" then
- profiles_xml = { "" }
- end
-
- local xml_string =
-[[
-<section name="configuration" description="FreeSwitch configuration for Sofia Profile">
-<configuration name="conference.conf" description="Conference configuration">
-<advertise>
-</advertise>
-<caller-controls>
-<group name="speaker">
-<control action="mute"/>
-<control action="deaf mute" digits="*"/>
-<control action="energy up" digits="9"/>
-<control action="energy equ" digits="8"/>
-<control action="energy dn" digits="7"/>
-<control action="vol talk up" digits="3"/>
-<control action="vol talk zero" digits="2"/>
-<control action="vol talk dn" digits="1"/>
-<control action="vol listen up" digits="6"/>
-<control action="vol listen zero" digits="5"/>
-<control action="vol listen dn" digits="4"/>
-<control action="hangup" digits="#"/>
-</group>
-<group name="moderator">
-<control action="mute" digits="0"/>
-<control action="deaf mute" digits="*"/>
-<control action="energy up" digits="9"/>
-<control action="energy equ" digits="8"/>
-<control action="energy dn" digits="7"/>
-<control action="vol talk up" digits="3"/>
-<control action="vol talk zero" digits="2"/>
-<control action="vol talk dn" digits="1"/>
-<control action="vol listen up" digits="6"/>
-<control action="vol listen zero" digits="5"/>
-<control action="vol listen dn" digits="4"/>
-<control action="hangup" digits="#"/>
-</group>
-</caller-controls>
-<profiles>
-]] .. table.concat(profiles_xml, "\n") .. [[
-
-</profiles>
-</configuration>
-</section>]]
- return xml_string
-end
-
-function FreeSwitchXml.conference_profile(self, profile_name, parameters)
- params_xml = {}
- for name, value in pairs(parameters) do
- params_xml[#params_xml+1] = self:param(name, value)
- end
-
- local xml_string =
-[[
-<profile name="]] .. profile_name .. [[">
-]] .. table.concat(params_xml, "\n") .. [[
-
-</profile>]]
- return xml_string
-end
diff --git a/misc/freeswitch/scripts/configuration/simple_xml.lua b/misc/freeswitch/scripts/configuration/simple_xml.lua
new file mode 100644
index 0000000..f04dd1e
--- /dev/null
+++ b/misc/freeswitch/scripts/configuration/simple_xml.lua
@@ -0,0 +1,50 @@
+-- Gemeinschaft 5 simple xml gererator class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+SimpleXml = {}
+
+-- Create SimpleXml object
+function SimpleXml.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'simplexml';
+ return object;
+end
+
+function SimpleXml.element(self, arg)
+ local xml_tag = '<' .. tostring(arg[1]);
+ for key, value in pairs(arg) do
+ if type(key) == 'string' then
+ xml_tag = xml_tag .. ' ' .. tostring(key) .. '="' .. tostring(value) .. '"';
+ end
+ end
+ xml_tag = xml_tag .. '>';
+
+ for key=2, #arg do
+ xml_tag = xml_tag .. '\n' .. tostring(arg[key]) .. '\n';
+ end
+
+ return xml_tag .. '</' .. tostring(arg[1]) .. '>';
+end
+
+
+function SimpleXml.from_hash(self, element_name, parameter_hash, key_name, value_name)
+ local params_xml = '';
+ for key, value in pairs(parameter_hash) do
+ local arguments = { [1] = element_name };
+ if key_name and value_name then
+ arguments[key_name] = key;
+ arguments[value_name] = value;
+ else
+ arguments[key] = value;
+ end
+ params_xml = params_xml .. tostring(self:element(arguments)) .. '\n';
+ end
+
+ return params_xml;
+end
diff --git a/misc/freeswitch/scripts/configuration/sip.lua b/misc/freeswitch/scripts/configuration/sip.lua
index 78143bc..6f5b204 100644
--- a/misc/freeswitch/scripts/configuration/sip.lua
+++ b/misc/freeswitch/scripts/configuration/sip.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: sip configuration class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -18,12 +18,6 @@ function Sip.new(self, arg)
return object;
end
--- find gateway by name
-function Sip.find_gateway_by_name(self, name)
- require 'common.configuration_file'
- return common.configuration_file.get('/opt/freeswitch/scripts/ini/gateways.ini', name);
-end
-
-- list sip domains
function Sip.domains(self)
local sql_query = 'SELECT * FROM `sip_domains`';
diff --git a/misc/freeswitch/scripts/dialplan/acd.lua b/misc/freeswitch/scripts/dialplan/acd.lua
index 563d836..f4b298e 100644
--- a/misc/freeswitch/scripts/dialplan/acd.lua
+++ b/misc/freeswitch/scripts/dialplan/acd.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: acd class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/cdr.lua b/misc/freeswitch/scripts/dialplan/cdr.lua
index 55a7889..d0fdede 100644
--- a/misc/freeswitch/scripts/dialplan/cdr.lua
+++ b/misc/freeswitch/scripts/dialplan/cdr.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: cdr class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/dialplan.lua b/misc/freeswitch/scripts/dialplan/dialplan.lua
index 391f5bf..b92dc70 100644
--- a/misc/freeswitch/scripts/dialplan/dialplan.lua
+++ b/misc/freeswitch/scripts/dialplan/dialplan.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: dialplan class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -7,7 +7,6 @@ module(...,package.seeall)
Dialplan = {}
-- local constants
-local CONFIG_FILE_NAME = '/opt/freeswitch/scripts/ini/dialplan.ini';
local DIAL_TIMEOUT = 120;
local MAX_LOOPS = 20;
local DIALPLAN_FUNCTION_PATTERN = '^f[_%-].*';
@@ -74,22 +73,22 @@ function Dialplan.domain_get(self, domain)
end
-function Dialplan.configuration_read(self, file_name)
+function Dialplan.configuration_read(self)
require 'common.str'
- require 'common.configuration_file'
+ require 'common.configuration_table'
-- dialplan configuration
- self.config = common.configuration_file.get(file_name or CONFIG_FILE_NAME);
+ self.config = common.configuration_table.get(self.database, 'dialplan');
self.node_id = common.str.to_i(self.config.parameters.node_id);
self.domain = self:domain_get(self.config.parameters.domain);
self.dial_timeout = tonumber(self.config.parameters.dial_timeout) or DIAL_TIMEOUT;
self.max_loops = tonumber(self.config.parameters.max_loops) or MAX_LOOPS;
self.user_image_url = common.str.to_s(self.config.parameters.user_image_url);
self.phone_book_entry_image_url = common.str.to_s(self.config.parameters.phone_book_entry_image_url);
- self.phonebook_number_lookup = common.str.to_b(self.config.parameters.phonebook_number_lookup);
- self.geo_number_lookup = common.str.to_b(self.config.parameters.geo_number_lookup);
+ self.phonebook_number_lookup = self.config.parameters.phonebook_number_lookup;
+ self.geo_number_lookup = self.config.parameters.geo_number_lookup;
self.default_language = self.config.parameters.default_language or 'en';
- self.send_ringing_to_gateways = common.str.to_b(self.config.parameters.send_ringing_to_gateways);
+ self.send_ringing_to_gateways = self.config.parameters.send_ringing_to_gateways;
if tonumber(self.config.parameters.default_ringtone) then
self.default_ringtone = 'http://amooma.de;info=Ringer' .. self.config.parameters.default_ringtone .. ';x-line-id=0';
@@ -113,57 +112,34 @@ function Dialplan.hangup(self, code, phrase, cause)
end
-function Dialplan.check_auth(self)
- local authenticated = false;
-
- require 'common.str'
- if self.caller.from_node then
- self.log:info('AUTH_FIRST_STAGE - node authenticated - node_id: ', self.caller.node_id);
- authenticated = true;
- elseif not common.str.blank(self.caller.auth_account_type) then
- self.log:info('AUTH_FIRST_STAGE - sipaccount autheticated by name/password: ', self.caller.auth_account_type, '=', self.caller.account_id, '/', self.caller.account_uuid);
- authenticated = true;
- elseif self.caller.from_gateway then
- self.log:info('AUTH_FIRST_STAGE - gateway autheticated by name/password: gateway=', self.caller.gateway_id, ', name: ', self.caller.gateway_name);
- authenticated = true;
- else
- local gateways = common.configuration_file.get('/opt/freeswitch/scripts/ini/gateways.ini', false);
- if not gateways then
- return false;
- end
- for gateway, gateway_parameters in pairs(gateways) do
- if common.str.to_s(gateway_parameters.proxy) == self.caller.sip_contact_host then
- self.caller.gateway_name = gateway;
- self.caller.from_gateway = true;
- self.log:info('AUTH_FIRST_STAGE - gateway autheticated by ip: gateway=', self.caller.gateway_id, ', name: ', self.caller.gateway_name, ', ip: ', self.caller.sip_contact_host);
- authenticated = true;
- end
- end
- end
-
- return authenticated;
-end
-
-
-function Dialplan.check_auth_node(self)
+function Dialplan.auth_node(self)
require 'common.node'
local node = common.node.Node:new{ log = self.log, database = self.database }:find_by_address(self.caller.sip_contact_host);
- return (node ~= nil);
+ if node then
+ self.log:info('AUTH_NODE - node_id: ', self.caller.node_id, ', contact address:', self.caller.sip_contact_host);
+ return true;
+ end
end
-function Dialplan.check_auth_ip(self)
- self.log:info('AUTH - node: ', self.caller.from_node, ', auth_account: ', self.caller.auth_account_type, ', gateway: ', self.caller.from_gateway);
+function Dialplan.auth_sip_account(self)
require 'common.str'
- if self.caller.from_node then
+ if not common.str.blank(self.caller.auth_account_type) then
+ self.log:info('AUTH_SIP_ACCOUNT - ', self.caller.auth_account_type, '=', self.caller.account_id, '/', self.caller.account_uuid);
return true;
- elseif not common.str.blank(self.caller.auth_account_type) then
- return true;
- elseif self.caller.from_gateway then
- return true;
- else
- return nil;
+ end
+end
+
+
+function Dialplan.auth_gateway(self)
+ require 'common.gateway'
+ local gateway_class = common.gateway.Gateway:new{ log = self.log, database = self.database};
+ local gateway = gateway_class:authenticate('sip', self.caller);
+
+ if gateway then
+ log:info('AUTH_GATEWAY - ', gateway.auth_source, ' ~ ', gateway.auth_pattern, ', gateway=', gateway.id, ', name: ', gateway.name, ', ip: ', self.caller.sip_contact_host);
+ return gateway_class:find_by_id(gateway.id);
end
end
@@ -258,19 +234,21 @@ end
function Dialplan.retrieve_caller_data(self)
- self.caller.caller_phone_numbers_hash = {}
-
require 'common.str'
- local dialed_sip_user = self.caller:to_s('dialed_user');
+ self.caller.caller_phone_numbers_hash = {}
-- TODO: Set auth_account on transfer initiated by calling party
- if not common.str.blank(dialed_sip_user) then
- self.caller.auth_account = self:object_find('sipaccount', self.caller:to_s('dialed_domain'), dialed_sip_user);
- self.caller:set_auth_account(self.caller.auth_account);
+ if not common.str.blank(self.caller.dialed_sip_user) then
+ self.caller.auth_account = self:object_find('sipaccount', self.caller.dialed_domain, dialed_sip_user);
+ if self.caller.set_auth_account then
+ self.caller:set_auth_account(self.caller.auth_account);
+ end
elseif not common.str.blank(self.caller.auth_account_type) and not common.str.blank(self.caller.auth_account_uuid) then
self.caller.auth_account = self:object_find(self.caller.auth_account_type, self.caller.auth_account_uuid);
- self.caller:set_auth_account(self.caller.auth_account);
+ if self.caller.set_auth_account then
+ self.caller:set_auth_account(self.caller.auth_account);
+ end
end
if self.caller.auth_account then
@@ -299,7 +277,7 @@ function Dialplan.retrieve_caller_data(self)
self.log:error('CALLER_DATA - caller owner not found');
end
- if not self.caller.clir then
+ if not self.caller.clir and self.caller.set_caller_id then
self.caller:set_caller_id(self.caller.caller_phone_numbers[1], self.caller.account.record.caller_name or self.caller.account.record.name);
end
else
@@ -366,12 +344,6 @@ function Dialplan.destination_new(self, arg)
end
-function Dialplan.routes_get(self, destination)
- require 'dialplan.route'
- return dialplan.route.Route:new{ log = self.log, database = self.database, routing_table = self.routes }:outbound(self.caller, destination.number);
-end
-
-
function Dialplan.set_caller_picture(self, entry_id, entry_type, image)
entry_type = entry_type:lower();
if entry_type == 'user' then
@@ -466,16 +438,13 @@ function Dialplan.dial(self, destination)
end
end
- if common.str.to_b(self.config.parameters.bypass_media) then
- self.caller:set_variable('bypass_media', true);
- end
-
require 'dialplan.sip_call'
return dialplan.sip_call.SipCall:new{ log = self.log, database = self.database, caller = self.caller }:fork(
destinations,
{ timeout = self.dial_timeout_active,
send_ringing = ( self.send_ringing_to_gateways and self.caller.from_gateway ),
bypass_media_network = self.config.parameters.bypass_media_network,
+ update_callee_display = self.config.parameters.update_callee_display,
}
);
end
@@ -655,9 +624,11 @@ function Dialplan.callthrough(self, destination)
return { continue = false, code = 404, phrase = 'No destination' }
end
- local route = dialplan.route.Route:new{ log = self.log, database = self.database, routing_table = self.routes }:prerouting(self.caller, destination_number);
- if route and route.value then
- destination_number = route.value;
+ require 'dialplan.router'
+ local route = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('prerouting', true);
+
+ if route and route.destination_number then
+ destination_number = route.destination_number;
end
if not callthrough:whitelist(destination_number) then
@@ -786,16 +757,30 @@ function Dialplan.switch(self, destination)
return self:dialplanfunction(destination);
elseif not common.str.blank(destination.number) then
local result = { continue = false, code = 404, phrase = 'No route' }
- local routes = self:routes_get(destination);
+
+ local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening');
+ self.caller.caller_id_numbers = {}
+ if not common.str.blank(clip_no_screening) then
+ for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do
+ table.insert(self.caller.caller_id_numbers, number);
+ end
+ end
+ for index, number in ipairs(self.caller.caller_phone_numbers) do
+ table.insert(self.caller.caller_id_numbers, number);
+ end
+ self.log:info('CALLER_ID_NUMBERS - clir: ', self.caller.clir, ', numbers: ', table.concat(self.caller.caller_id_numbers, ','));
+
+ destination.callee_id_number = destination.number;
+ destination.callee_id_name = nil;
+
+ require 'dialplan.router'
+ local routes = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('outbound');
if not routes or #routes == 0 then
self.log:notice('SWITCH - no route - number: ', destination.number);
return { continue = false, code = 404, phrase = 'No route' }
end
- destination.callee_id_number = destination.number;
- destination.callee_id_name = nil;
-
if self.phonebook_number_lookup then
require 'common.str'
local user_id = common.str.try(self.caller, 'account.owner.id');
@@ -828,26 +813,26 @@ function Dialplan.switch(self, destination)
self.caller:set_callee_id(destination.callee_id_number, destination.callee_id_name);
for index, route in ipairs(routes) do
- if route.class == 'hangup' then
+ if route.endpoint_type == 'hangup' then
return { continue = false, code = route.endpoint, phrase = route.phrase, cause = route.value }
end
- if route.class == 'forward' then
+ if route.endpoint_type == 'forward' then
return { continue = true, call_forwarding = { number = route.value, service = 'route', type = 'phonenumber' }}
end
- destination.gateway = route.endpoint;
- destination.type = route.class;
- destination.number = route.value;
- destination.caller_id_number = route.caller_id_number;
- destination.caller_id_name = route.caller_id_name;
+
+ for key, value in pairs(route) do
+ destination[key] = value;
+ end
+
result = self:dial(destination);
if result.continue == false then
break;
end
- if common.str.to_b(self.routes.failover[tostring(result.code)]) == true then
+ if common.str.to_b(self.route_failover[tostring(result.code)]) == true then
self.log:info('SWITCH - failover - code: ', result.code);
- elseif common.str.to_b(self.routes.failover[tostring(result.cause)]) == true then
+ elseif common.str.to_b(self.route_failover[tostring(result.cause)]) == true then
self.log:info('SWITCH - failover - cause: ', result.cause);
else
self.log:info('SWITCH - no failover - cause: ', result.cause, ', code: ', result.code);
@@ -864,10 +849,11 @@ end
function Dialplan.run(self, destination)
+ require 'common.str';
+ require 'dialplan.router';
+
self.caller:set_variable('hangup_after_bridge', false);
- self.caller:set_variable('ringback', self.config.parameters.ringback);
self.caller:set_variable('bridge_early_media', 'true');
- self.caller:set_variable('send_silence_when_idle', 0);
self.caller:set_variable('default_language', self.default_language);
self.caller:set_variable('gs_save_cdr', true);
self.caller:set_variable('gs_call_service', 'dial');
@@ -875,30 +861,69 @@ function Dialplan.run(self, destination)
self.caller.date = os.date('%y%m%d%w');
self.caller.time = os.date('%H%M%S');
- self.routes = common.configuration_file.get('/opt/freeswitch/scripts/ini/routes.ini');
+ if type(self.config.variables) == 'table' then
+ for key, value in pairs(self.config.variables) do
+ self.caller:set_variable(key, value);
+ end
+ end
+
self.caller.domain_local = self.domain;
self:retrieve_caller_data();
+ self.route_failover = common.configuration_table.get(self.database, 'call_route', 'failover');
if not destination or destination.type == 'unknown' then
- require 'dialplan.route'
local route = nil;
+ if self.caller.gateway then
+ if not common.str.blank(self.caller.gateway.settings.number_source) then
+ self.log:debug('INBOUND_NUMBER: number_source: ', self.caller.gateway.settings.number_source, ', number: ', self.caller:to_s(self.caller.gateway.settings.number_source));
+ self.caller.destination_number = self.caller:to_s(self.caller.gateway.settings.number_source);
+ end
- if self.caller.from_gateway then
- local route_object = dialplan.route.Route:new{ log = self.log, database = self.database, routing_table = self.routes };
- route = route_object:inbound(self.caller, self.caller.destination_number);
- local inbound_caller_id_number = route_object:inbound_cid_number(self.caller, self.caller.gateway_name, 'gateway');
- route_object.expandable.caller_id_number = inbound_caller_id_number;
- local inbound_caller_id_name = route_object:inbound_cid_name(self.caller, self.caller.gateway_name, 'gateway');
- self.log:info('INBOUND_CALLER_ID_REWRITE - number: ', inbound_caller_id_number, ', name: ', inbound_caller_id_name);
- self.caller.caller_id_number = inbound_caller_id_number or self.caller.caller_id_number;
- self.caller.caller_id_name = inbound_caller_id_name or self.caller.caller_id_name;
- self.caller.caller_phone_numbers[1] = self.caller.caller_id_number;
+ route = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('inbound', true);
+ if route then
+ local ignore_keys = {
+ id = true,
+ gateway = true,
+ ['type'] = true,
+ channel_variables = true,
+ };
+
+ for key, value in pairs(route) do
+ if not ignore_keys[key] then
+ self.caller[key] = value;
+ end
+ end
+
+ self.caller.caller_phone_numbers[1] = self.caller.caller_id_number;
+ else
+ self.log:notice('INBOUND - no route');
+ end
else
- route = dialplan.route.Route:new{ log = self.log, database = self.database, routing_table = self.routes }:prerouting(self.caller, self.caller.destination_number);
+ route = dialplan.router.Router:new{ log = self.log, database = self.database, caller = self.caller, variables = self.caller }:route_run('prerouting', true);
+ if route then
+ local ignore_keys = {
+ id = true,
+ gateway = true,
+ ['type'] = true,
+ channel_variables = true,
+ };
+
+ for key, value in pairs(route) do
+ if not ignore_keys[key] then
+ self.caller[key] = value;
+ end
+ end
+ end
end
if route then
- destination = self:destination_new{ number = route.value }
+ if type(route.channel_variables) == 'table' then
+ for key, value in pairs(route.channel_variables) do
+ self.caller:set_variable(key, value);
+ end
+ end
+
+ destination = self:destination_new{ ['type'] = route.type, id = route.id, number = route.destination_number }
self.caller.destination_number = destination.number;
self.caller.destination = destination;
elseif not destination or destination.type == 'unknown' then
@@ -979,6 +1004,7 @@ function Dialplan.run(self, destination)
self.log:info('LOOP ', loop, ' NEW_DESTINATION_NUMBER - number: ', result.number );
destination = self:destination_new{ number = result.number }
self.caller.destination = destination;
+ self.caller.destination_number = destination.number;
end
end
diff --git a/misc/freeswitch/scripts/dialplan/fax.lua b/misc/freeswitch/scripts/dialplan/fax.lua
index 2a40620..aa29ff6 100644
--- a/misc/freeswitch/scripts/dialplan/fax.lua
+++ b/misc/freeswitch/scripts/dialplan/fax.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: fax class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/functions.lua b/misc/freeswitch/scripts/dialplan/functions.lua
index 9a89857..2ca51c8 100644
--- a/misc/freeswitch/scripts/dialplan/functions.lua
+++ b/misc/freeswitch/scripts/dialplan/functions.lua
@@ -51,10 +51,16 @@ function Functions.dialplan_function(self, caller, dialed_number)
result = self:user_auto_logout(caller, true);
elseif fid == "loaoff" then
result = self:user_auto_logout(caller, false);
+ elseif fid == "redial" then
+ result = self:redial(caller);
elseif fid == "dcliroff" then
result = self:dial_clir_off(caller, parameters[3]);
elseif fid == "dcliron" then
result = self:dial_clir_on(caller, parameters[3]);
+ elseif fid == "cliron" then
+ result = self:clir_on(caller);
+ elseif fid == "cliroff" then
+ result = self:clir_off(caller);
elseif fid == "clipon" then
result = self:clip_on(caller);
elseif fid == "clipoff" then
@@ -503,6 +509,30 @@ function Functions.user_auto_logout(self, caller, auto_logout)
caller:sleep(1000);
end
+function Functions.redial(self, caller)
+ -- Ensure a valid sip account
+ local caller_sip_account = self:ensure_caller_sip_account(caller);
+ if not caller_sip_account then
+ return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true }
+ end
+
+ local sql_query = 'SELECT `destination_number` \
+ FROM `call_histories` \
+ WHERE `entry_type` = "dialed" \
+ AND `call_historyable_type` = "SipAccount" \
+ AND `call_historyable_id` = ' .. caller_sip_account.record.id .. ' \
+ ORDER BY `start_stamp` DESC LIMIT 1';
+
+ local phone_number = self.database:query_return_value(sql_query);
+
+ common_str = require 'common.str';
+ if common_str.blank(phone_number) then
+ return { continue = false, code = 404, phrase = 'No phone number saved', no_cdr = true }
+ end
+
+ return { continue = true, number = phone_number }
+end
+
function Functions.dial_clir_off(self, caller, phone_number)
-- Ensure a valid sip account
local caller_sip_account = self:ensure_caller_sip_account(caller);
@@ -565,6 +595,48 @@ function Functions.callwaiting_off(self, caller)
return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
end
+function Functions.clir_on(self, caller)
+ -- Find caller's SipAccount
+ local caller_sip_account = self:ensure_caller_sip_account(caller);
+ if not caller_sip_account then
+ return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true }
+ end
+
+ local sql_query = 'UPDATE `sip_accounts` SET `clir` = TRUE WHERE `id` = ' .. caller_sip_account.record.id;
+
+ if not self.database:query(sql_query) then
+ self.log:notice("CLIR could not be set");
+ return { continue = false, code = 500, phrase = 'CLIR could not be set', no_cdr = true }
+
+ end
+
+ caller:answer();
+ caller:send_display('CLIR on');
+ caller:sleep(1000);
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
+end
+
+function Functions.clir_off(self, caller)
+ -- Find caller's SipAccount
+ local caller_sip_account = self:ensure_caller_sip_account(caller);
+ if not caller_sip_account then
+ return { continue = false, code = 403, phrase = 'Incompatible caller', no_cdr = true }
+ end
+
+ local sql_query = 'UPDATE `sip_accounts` SET `clir` = FALSE WHERE `id` = ' .. caller_sip_account.record.id;
+
+ if not self.database:query(sql_query) then
+ self.log:notice("CLIR could not be set");
+ return { continue = false, code = 500, phrase = 'CLIR could not be set', no_cdr = true }
+
+ end
+
+ caller:answer();
+ caller:send_display('CLIR off');
+ caller:sleep(1000);
+ return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
+end
+
function Functions.clip_on(self, caller)
-- Find caller's SipAccount
local caller_sip_account = self:ensure_caller_sip_account(caller);
@@ -586,6 +658,7 @@ function Functions.clip_on(self, caller)
return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
end
+
function Functions.clip_off(self, caller)
-- Find caller's SipAccount
local caller_sip_account = self:ensure_caller_sip_account(caller);
@@ -607,7 +680,6 @@ function Functions.clip_off(self, caller)
return { continue = false, code = 200, phrase = 'OK', no_cdr = true }
end
-
function Functions.call_forwarding_off(self, caller, call_forwarding_service, delete)
local defaults = {log = self.log, database = self.database, domain = caller.domain}
diff --git a/misc/freeswitch/scripts/dialplan/geo_number.lua b/misc/freeswitch/scripts/dialplan/geo_number.lua
index 06bfd62..76cc01b 100644
--- a/misc/freeswitch/scripts/dialplan/geo_number.lua
+++ b/misc/freeswitch/scripts/dialplan/geo_number.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: geonumber class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/hunt_group.lua b/misc/freeswitch/scripts/dialplan/hunt_group.lua
index 87f86f1..2c73bf8 100644
--- a/misc/freeswitch/scripts/dialplan/hunt_group.lua
+++ b/misc/freeswitch/scripts/dialplan/hunt_group.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: hunt group class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -98,21 +98,33 @@ function HuntGroup.run(self, dialplan_object, caller, destination)
self.log:info('HUNTGROUP ', self.record.id, ' - name: ', self.record.name, ', strategy: ', self.record.strategy,', members: ', #hunt_group_members);
+ local save_destination = caller.destination;
+
local destinations = {}
for index, hunt_group_member in ipairs(hunt_group_members) do
local destination = dialplan_object:destination_new{ number = hunt_group_member.number };
if destination.type == 'unknown' then
- require 'dialplan.route'
- local routes = dialplan.route.Route:new{ log = self.log, database = self.database, routing_table = dialplan_object.routes }:outbound(caller, destination.number);
- if routes and #routes > 0 then
- destination.callee_id_number = destination.number;
- destination.callee_id_name = nil;
- local route = routes[1];
- destination.gateway = route.endpoint;
- destination.type = route.class;
- destination.number = route.value;
- destination.caller_id_number = route.caller_id_number;
- destination.caller_id_name = route.caller_id_name;
+
+ caller.destination_number = destination.number;
+
+ require 'dialplan.router'
+ local route = dialplan.router.Router:new{ log = self.log, database = self.database, caller = caller, variables = caller }:route_run('outbound', true);
+
+ if route then
+ destination = dialplan_object:destination_new{ ['type'] = route.type, id = route.id, number = route.destination_number }
+
+ local ignore_keys = {
+ id = true,
+ ['type'] = true,
+ channel_variables = true,
+ };
+
+ for key, value in pairs(route) do
+ if not ignore_keys[key] then
+ destination[key] = value;
+ end
+ end
+
table.insert(destinations, destination);
end
else
@@ -120,6 +132,9 @@ function HuntGroup.run(self, dialplan_object, caller, destination)
end
end
+ caller.destination = save_destination;
+ caller.destination_number = save_destination.number;
+
local forwarding_destination = nil;
if caller.forwarding_service == 'assistant' and caller.auth_account then
forwarding_destination = dialplan_object:destination_new{ type = caller.auth_account.class, id = caller.auth_account.id, number = forwarding_number }
diff --git a/misc/freeswitch/scripts/dialplan/phone_book.lua b/misc/freeswitch/scripts/dialplan/phone_book.lua
index 089f115..6653789 100644
--- a/misc/freeswitch/scripts/dialplan/phone_book.lua
+++ b/misc/freeswitch/scripts/dialplan/phone_book.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: phone book class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/presence.lua b/misc/freeswitch/scripts/dialplan/presence.lua
index 234b908..0f63ce9 100644
--- a/misc/freeswitch/scripts/dialplan/presence.lua
+++ b/misc/freeswitch/scripts/dialplan/presence.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: presence class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/route.lua b/misc/freeswitch/scripts/dialplan/route.lua
deleted file mode 100644
index 2243cbe..0000000
--- a/misc/freeswitch/scripts/dialplan/route.lua
+++ /dev/null
@@ -1,265 +0,0 @@
--- Gemeinschaft 5 module: routing class
--- (c) AMOOMA GmbH 2012
---
-
-module(...,package.seeall)
-
-Route = {}
-
--- create route object
-function Route.new(self, arg)
- arg = arg or {}
- object = arg.object or {}
- setmetatable(object, self);
- self.__index = self;
- self.log = arg.log;
- self.database = arg.database;
- self.routing_table = arg.routing_table;
- self.expandable = arg.expandable or {};
- return object;
-end
-
--- find matching routes
-function Route.prerouting(self, caller, number)
- require 'common.routing_tables'
-
- for index, routing_entry in pairs(self.routing_table.prerouting) do
- local route = common.routing_tables.match_route(routing_entry, number);
- if route.error then
- self.log:error('PREROUTE - error: ', route.error);
- elseif route.value then
- self.log:info('ROUTE_PREROUTING - called number: ', number, ', value: ', route.value, ', pattern: ', route.pattern);
- return route;
- end
- end
-end
-
--- find matching routes
-function Route.outbound(self, caller, number)
- local routes = {};
- require 'common.routing_tables'
- require 'common.str'
-
- local ignore_arguments = {
- class=true,
- endpoint=true,
- pattern=true,
- value=true,
- group=true,
- phrase=true,
- }
-
- local clip_no_screening = common.str.try(caller, 'account.record.clip_no_screening');
- local caller_id_numbers = {}
- if not common.str.blank(clip_no_screening) then
- for index, number in ipairs(common.str.strip_to_a(clip_no_screening, ',')) do
- table.insert(caller_id_numbers, number);
- end
- end
- for index, number in ipairs(caller.caller_phone_numbers) do
- table.insert(caller_id_numbers, number);
- end
- self.log:info('CALLER_ID_NUMBER - caller_id_numbers: ', table.concat(caller_id_numbers, ','));
-
- for index, routing_entry in pairs(self.routing_table.outbound) do
- local route = common.routing_tables.match_route(routing_entry, number);
- if route.error then
- self.log:error('ROUTE_OUTBOUND - error: ', route.error);
- elseif route.value then
- local valid_route = true;
-
- for argument, value in pairs(route) do
- if not ignore_arguments[argument] then
- local table_value = common.str.downcase(tostring(common.str.try(caller, argument)));
- value = common.str.downcase(tostring(value));
- if table_value:match(value) then
- self.log:info('ROUTE_OUTBOUND_POSITIVE - ', argument, '=', value, ' ~ ', table_value, ', pattern: ', route.pattern);
- else
- self.log:info('ROUTE_OUTBOUND_NEGATIVE - ', argument, '=', value, ' !~ ', table_value, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
- end
-
- if route.group then
- if common.str.try(caller.auth_account, 'owner.groups.' .. tostring(route.group)) then
- self.log:info('ROUTE_OUTBOUND_POSITIVE - group=', route.group, ', pattern: ', route.pattern);
- else
- self.log:info('ROUTE_OUTBOUND_NEGATIVE - group=', route.group, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
-
- if route.cidn then
- if caller.caller_id_number:match(route.cidn) then
- self.log:info('ROUTE_OUTBOUND_POSITIVE - cidn=', route.cidn, ' ~ ', caller.caller_id_number,', pattern: ', route.pattern);
- else
- self.log:info('ROUTE_OUTBOUND_NEGATIVE - cidn=', route.cidn, ' !~ ', caller.caller_id_number, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
-
- if valid_route then
- if route.class ~= 'hangup' then
- route.caller_id_number = self:outbound_cid_number(caller, caller_id_numbers, route.endpoint, route.class);
- self.expandable.caller_id_number = route.caller_id_number;
- route.caller_id_name = self:outbound_cid_name(caller, route.endpoint, route.class);
- end
- table.insert(routes, route);
- self.log:info('ROUTE_OUTBOUND ', #routes,' - ', route.class, '=', route.endpoint, ', value: ', route.value, ', caller_id_number: ', route.caller_id_number, ', caller_id_name: ', route.caller_id_name);
- end
- end
- end
-
- return routes;
-end
-
-
-function Route.inbound(self, caller, number)
- require 'common.routing_tables'
-
- local ignore_arguments = {
- class=true,
- endpoint=true,
- pattern=true,
- value=true,
- group=true,
- phrase=true,
- }
-
- for index, routing_entry in pairs(self.routing_table.inbound) do
- local route = common.routing_tables.match_route(routing_entry, number);
- if route.error then
- self.log:error('ROUTE_INBOUND - error: ', route.error);
- elseif route.value then
- local valid_route = true;
-
- for argument, value in pairs(route) do
- if not ignore_arguments[argument] then
- local table_value = common.str.downcase(tostring(common.str.try(caller, argument)));
- value = common.str.downcase(tostring(value));
- if table_value:match(value) then
- self.log:info('ROUTE_INBOUND_POSITIVE - ', argument, '=', value, ' ~ ', table_value, ', pattern: ', route.pattern);
- else
- self.log:info('ROUTE_INBOUND_NEGATIVE - ', argument, '=', value, ' !~ ', table_value, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
- end
-
- if route.class and route.endpoint then
- if route.class == 'gateway' and caller.gateway_name:match(route.endpoint) then
- self.log:info('ROUTE_INBOUND_POSITIVE - ', route.class, '=', route.endpoint, ' ~ ', caller.gateway_name, ', pattern: ', route.pattern);
- else
- self.log:info('ROUTE_INBOUND_NEGATIVE - ', route.class, '=', route.endpoint, ' !~ ', caller.gateway_name, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
-
- if valid_route then
- self.log:info('ROUTE_INBOUND - called number: ', number, ', value: ', route.value, ', pattern: ', route.pattern);
- return route;
- end
- end
- end
-end
-
--- find caller id
-function Route.caller_id(self, caller, cid_entry, search_str, endpoint, class)
- local ignore_arguments = {
- class=true,
- endpoint=true,
- pattern=true,
- value=true,
- group=true,
- phrase=true,
- }
-
- local route = common.routing_tables.match_route(cid_entry, search_str, self.expandable);
- if route.error then
- self.log:error('CALLER_ID - error: ', route.error);
- elseif route.value then
- local valid_route = true;
-
- for argument, value in pairs(route) do
- if not ignore_arguments[argument] then
- local table_value = common.str.downcase(tostring(common.str.try(caller, argument)));
- value = common.str.downcase(tostring(value));
- if table_value:match(value) then
- self.log:debug('CALLER_ID_POSITIVE - ', argument, '=', value, ' ~ ', table_value, ', pattern: ', route.pattern);
- else
- self.log:debug('CALLER_ID_NEGATIVE - ', argument, '=', value, ' !~ ', table_value, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
- end
-
- if route.group then
- if common.str.try(caller.auth_account, 'owner.groups.' .. tostring(route.group)) then
- self.log:debug('CALLER_ID_POSITIVE - group=', route.group, ', pattern: ', route.pattern);
- else
- self.log:debug('CALLER_ID_NEGATIVE - group=', route.group, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
-
- endpoint = tostring(endpoint);
- if route.class and route.endpoint then
- if route.class == 'gateway' and endpoint:match(route.endpoint) then
- self.log:debug('CALLER_ID_POSITIVE - ', route.class, '=', route.endpoint, ' ~ ', endpoint, ', pattern: ', route.pattern);
- else
- self.log:debug('CALLER_ID_NEGATIVE - ', route.class, '=', route.endpoint, ' !~ ', endpoint, ', pattern: ', route.pattern);
- valid_route = false;
- end
- end
-
- if valid_route then
- self.log:debug('CALLER_ID ', route.class, '=', route.endpoint, ', value: ', route.value);
- return route.value;
- end
- end
-
- return nil;
-end
-
--- find matching caller id number
-function Route.outbound_cid_number(self, caller, caller_id_numbers, endpoint, class)
- for route_index, cid_entry in pairs(self.routing_table.outbound_cid_number) do
- for index, number in ipairs(caller_id_numbers) do
- local route = self:caller_id(caller, cid_entry, number, endpoint, class);
- if route then
- return route;
- end
- end
- end
-end
-
--- find matching caller id name
-function Route.outbound_cid_name(self, caller, endpoint, class)
- for route_index, cid_entry in pairs(self.routing_table.outbound_cid_name) do
- local route = self:caller_id(caller, cid_entry, caller.caller_id_name, endpoint, class);
- if route then
- return route;
- end
- end
-end
-
--- find matching caller id number
-function Route.inbound_cid_number(self, caller, endpoint, class)
- for route_index, cid_entry in pairs(self.routing_table.inbound_cid_number) do
- local route = self:caller_id(caller, cid_entry, caller.caller_id_number, endpoint, class);
- if route then
- return route;
- end
- end
-end
-
--- find matching caller id name
-function Route.inbound_cid_name(self, caller, endpoint, class)
- for route_index, cid_entry in pairs(self.routing_table.inbound_cid_name) do
- local route = self:caller_id(caller, cid_entry, caller.caller_id_name, endpoint, class);
- if route then
- return route;
- end
- end
-end
diff --git a/misc/freeswitch/scripts/dialplan/router.lua b/misc/freeswitch/scripts/dialplan/router.lua
new file mode 100644
index 0000000..7e64d7b
--- /dev/null
+++ b/misc/freeswitch/scripts/dialplan/router.lua
@@ -0,0 +1,187 @@
+-- Gemeinschaft 5 module: call router class
+-- (c) AMOOMA GmbH 2013
+--
+
+module(...,package.seeall)
+
+Router = {}
+
+-- create route object
+function Router.new(self, arg)
+ arg = arg or {}
+ object = arg.object or {}
+ setmetatable(object, self);
+ self.__index = self;
+ self.class = 'router';
+ self.log = arg.log;
+ self.database = arg.database;
+ self.routes = arg.routes or {};
+ self.caller = arg.caller;
+ self.variables = arg.variables or {};
+ return object;
+end
+
+
+function Router.read_table(self, table_name)
+ local routing_table = {};
+
+ local sql_query = 'SELECT * \
+ FROM `call_routes` `a` \
+ JOIN `route_elements` `b` ON `a`.`id` = `b`.`call_route_id`\
+ WHERE `a`.`routing_table` = "' .. table_name .. '" \
+ ORDER BY `a`.`position`, `b`.`position`';
+
+ local last_id = 0;
+ self.database:query(sql_query, function(route)
+ if last_id ~= tonumber(route.call_route_id) then
+ last_id = tonumber(route.call_route_id);
+ table.insert(routing_table, {id = route.call_route_id, name = route.name, endpoint_type = route.endpoint_type , endpoint_id = route.endpoint_id, elements = {} });
+ end
+
+ table.insert(routing_table[#routing_table].elements, {
+ var_in = route.var_in,
+ var_out = route.var_out,
+ pattern = route.pattern,
+ replacement = route.replacement,
+ action = route.action,
+ mandatory = common.str.to_b(route.mandatory),
+ });
+ end);
+
+ return routing_table;
+end
+
+
+function Router.expand_variables(self, line, variables)
+ return (line:gsub('{([%a%d%._]+)}', function(captured)
+ return common.str.try(variables, captured) or '';
+ end))
+end
+
+
+function Router.element_match(self, pattern, search_string, replacement)
+ local success, result = pcall(string.find, search_string, pattern);
+
+ if not success then
+ self.log:error('ELEMENT_MATCH - table error - pattern: ', pattern, ', search_string: ', search_string);
+ elseif result then
+ return true, search_string:gsub(pattern, self:expand_variables(replacement, self.variables));
+ end
+
+ return false;
+end
+
+
+function Router.element_match_group(self, pattern, groups, replacement, use_key)
+ if type(groups) ~= 'table' then
+ return false;
+ end
+
+ for key, value in pairs(groups) do
+ if use_key then
+ value = key;
+ end
+ result, replaced_value = self:element_match(pattern, tostring(value), replacement);
+ if result then
+ return true, replaced_value;
+ end
+ end
+end
+
+
+function Router.route_match(self, route)
+ local destination = {
+ gateway = 'gateway' .. route.endpoint_id,
+ ['type'] = route.endpoint_type,
+ id = route.endpoint_id,
+ channel_variables = {}
+ };
+
+ local route_matches = false;
+
+ for index=1, #route.elements do
+ local result = false;
+ local replacement = nil;
+
+ local element = route.elements[index];
+
+ if element.action ~= 'none' then
+ if common.str.blank(element.var_in) or common.str.blank(element.pattern) and element.action == 'set' then
+ result = true;
+ replacement = self:expand_variables(element.replacement, self.variables);
+ else
+ local command, variable_name = common.str.partition(element.var_in, ':');
+
+ if not command or not variable_name or command == 'var' then
+ local search_string = tostring(common.str.try(self.caller, element.var_in))
+ result, replacement = self:element_match(tostring(element.pattern), tostring(search_string), tostring(element.replacement));
+ elseif command == 'key' or command == 'val' then
+ local groups = common.str.try(self.caller, variable_name);
+ result, replacement = self:element_match_group(tostring(element.pattern), groups, tostring(element.replacement), command == 'key');
+ elseif command == 'chv' then
+ local search_string = self.caller:to_s(variable_name);
+ result, replacement = self:element_match(tostring(element.pattern), search_string, tostring(element.replacement));
+ elseif command == 'hdr' then
+ local search_string = self.caller:to_s('sip_h_' .. variable_name);
+ result, replacement = self:element_match(tostring(element.pattern), search_string, tostring(element.replacement));
+ end
+ end
+
+ if element.action == 'not_match' then
+ result = not result;
+ end
+
+ if not result then
+ if element.mandatory then
+ return false;
+ end
+ else
+ if not common.str.blank(element.var_out) then
+ local command, variable_name = common.str.partition(element.var_out, ':');
+ if not command or not variable_name or command == 'var' then
+ destination[element.var_out] = replacement;
+ elseif command == 'chv' then
+ destination.channel_variables[variable_name] = replacement;
+ elseif command == 'hdr' then
+ destination.channel_variables['sip_h_' .. variable_name] = replacement;
+ end
+ end
+
+ if element.action == 'match' or element.action == 'not_match' then
+ route_matches = true;
+ end
+ end
+ end
+ end
+
+ if route_matches then
+ return destination;
+ end;
+
+ return nil;
+end
+
+
+function Router.route_run(self, table_name, find_first)
+ local routing_table = self:read_table(table_name);
+ local routes = {};
+
+ if type(routing_table) == 'table' then
+ for index=1, #routing_table do
+ local route = self:route_match(routing_table[index]);
+ if route then
+ table.insert(routes, route);
+ self.log:info('ROUTE ', #routes,' - ', table_name,'=', routing_table[index].id, '/', routing_table[index].name, ', destination: ', route.type, '=', route.id, ', destination_number: ', route.destination_number);
+ if find_first then
+ return route;
+ end
+ else
+ self.log:debug('ROUTE_NO_MATCH - ', table_name, '=', routing_table[index].id, '/', routing_table[index].name);
+ end
+ end
+ end
+
+ if not find_first then
+ return routes;
+ end
+end
diff --git a/misc/freeswitch/scripts/dialplan/session.lua b/misc/freeswitch/scripts/dialplan/session.lua
index 7174b24..7de85ca 100644
--- a/misc/freeswitch/scripts/dialplan/session.lua
+++ b/misc/freeswitch/scripts/dialplan/session.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: caller session class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -43,9 +43,13 @@ function Session.init_channel_variables(self)
self.from_gateway = true;
end
+ self.dialed_sip_user = self:to_s('dialed_user');
+ self.dialed_domain = self:to_s('dialed_domain');
+
self.account_uuid = self:to_s('gs_account_uuid');
self.account_type = self:to_s('gs_account_type');
self.sip_contact_host = self:to_s('sip_contact_host');
+ self.sip_network_ip = self:to_s('sip_network_ip');
self.clir = self:to_b('gs_clir');
self.call_timeout = self:to_i('gs_call_timeout');
self.auth_account_type = self:to_s('gs_auth_account_type');
diff --git a/misc/freeswitch/scripts/dialplan/sip_call.lua b/misc/freeswitch/scripts/dialplan/sip_call.lua
index 57f92c6..3f56753 100644
--- a/misc/freeswitch/scripts/dialplan/sip_call.lua
+++ b/misc/freeswitch/scripts/dialplan/sip_call.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: sip call class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall);
@@ -79,6 +79,8 @@ function SipCall.fork(self, destinations, arg )
local dial_strings = {}
require 'common.sip_account'
+ require 'common.str'
+
local sip_account_class = common.sip_account.SipAccount:new{ log = self.log, database = self.database };
local call_result = { code = 404, phrase = 'No destination' };
@@ -87,7 +89,12 @@ function SipCall.fork(self, destinations, arg )
for index, destination in ipairs(destinations) do
local origination_variables = { 'gs_fork_index=' .. index }
- self.log:info('FORK ', index, '/', #destinations, ' - ', destination.type, '=', destination.id, '/', destination.gateway or destination.uuid, '@', destination.node_id, ', number: ', destination.number);
+ self.log:info('FORK ', index, '/', #destinations, ' - ', destination.type, '=', destination.id, '/', destination.gateway or destination.uuid, '@', destination.node_id, ', number: ', destination.number, ', caller_id: "', destination.caller_id_name, '" <', destination.caller_id_number, '>');
+
+ if not common.str.to_b(arg.update_callee_display) then
+ table.insert(origination_variables, 'ignore_display_updates=true');
+ end
+
if not destination.node_local or destination.type == 'node' then
require 'common.node'
local node = nil;
@@ -128,7 +135,12 @@ function SipCall.fork(self, destinations, arg )
if destination.caller_id_name then
table.insert(origination_variables, "origination_caller_id_name='" .. destination.caller_id_name .. "'");
end
- table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. destination.gateway .. '/' .. destination.number);
+ if destination.channel_variables then
+ for key, value in pairs(destination.channel_variables) do
+ table.insert(origination_variables, tostring(key) .. "='" .. tostring(value) .. "'");
+ end
+ end
+ table.insert(dial_strings, '[' .. table.concat(origination_variables , ',') .. ']sofia/gateway/' .. tostring(destination.gateway) .. '/' .. tostring(destination.number));
elseif destination.type == 'dial' then
if destination.caller_id_number then
table.insert(origination_variables, "origination_caller_id_number='" .. destination.caller_id_number .. "'");
diff --git a/misc/freeswitch/scripts/dialplan/tenant.lua b/misc/freeswitch/scripts/dialplan/tenant.lua
index 8d6436c..904609e 100644
--- a/misc/freeswitch/scripts/dialplan/tenant.lua
+++ b/misc/freeswitch/scripts/dialplan/tenant.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: user class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/dialplan/user.lua b/misc/freeswitch/scripts/dialplan/user.lua
index 3b483c8..b536600 100644
--- a/misc/freeswitch/scripts/dialplan/user.lua
+++ b/misc/freeswitch/scripts/dialplan/user.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: user class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -62,7 +62,7 @@ function User.list_groups(self, id)
local groups = {};
self.database:query(sql_query, function(entry)
- groups[common.str.downcase(entry.name)] = true;
+ table.insert(groups, common.str.downcase(entry.name));
end);
return groups;
diff --git a/misc/freeswitch/scripts/dialplan/voicemail.lua b/misc/freeswitch/scripts/dialplan/voicemail.lua
index b9dab79..5d79ba3 100644
--- a/misc/freeswitch/scripts/dialplan/voicemail.lua
+++ b/misc/freeswitch/scripts/dialplan/voicemail.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: voicemail class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -128,7 +128,7 @@ end
function Voicemail.send_notify(self, caller)
self.log:debug('VOICEMAIL_NOTIFY - account: ' .. self.record.auth_name .. ", id: " .. tostring(caller.uuid));
- local file = io.popen("/opt/GS5/script/voicemail_new.sh '" .. tostring(self.record.auth_name) .. "' '" .. tostring(caller.uuid) .. "' 2>&1");
+ local file = io.popen("/opt/GS5/script/voicemail_new '" .. tostring(self.record.auth_name) .. "' '" .. tostring(caller.uuid) .. "' 2>&1");
self.log:debug('VOICEMAIL_NOTIFY - result: ' .. tostring(file:read("*a")));
file:close();
diff --git a/misc/freeswitch/scripts/dialplan_default.lua b/misc/freeswitch/scripts/dialplan_default.lua
index ee4a88f..7caff57 100644
--- a/misc/freeswitch/scripts/dialplan_default.lua
+++ b/misc/freeswitch/scripts/dialplan_default.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 default dialplan
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
@@ -23,33 +23,50 @@ log = common.log.Log:new{ prefix = '### [' .. session:get_uuid() .. '] ' };
require 'dialplan.session'
start_caller = dialplan.session.Session:new{ log = log, session = session };
+-- connect to database
+require 'common.database'
+local database = common.database.Database:new{ log = log }:connect();
+if not database:connected() then
+ log:critical('DIALPLAN_DEFAULT - database connect failed');
+ return;
+end
+
-- dialplan object
require 'dialplan.dialplan'
-start_dialplan = dialplan.dialplan.Dialplan:new{ log = log, caller = start_caller };
+local start_dialplan = dialplan.dialplan.Dialplan:new{ log = log, caller = start_caller, database = database };
start_dialplan:configuration_read();
start_caller.local_node_id = start_dialplan.node_id;
start_caller:init_channel_variables();
--- session:execute('info','notice');
-
-if not start_dialplan:check_auth() then
- log:debug('AUTHENTICATION_REQUIRED - domain: ', start_dialplan.domain);
- start_dialplan:hangup(407, start_dialplan.domain);
- return false;
+if start_dialplan.config.parameters.dump_variables then
+ start_caller:execute('info', 'notice');
end
--- connect to database
-require 'common.database'
-local database = common.database.Database:new{ log = log }:connect();
-if not database:connected() then
- log:critical('DIALPLAN_DEFAULT - database connect failed');
- return;
-end
+if start_caller.from_node and not start_dialplan:auth_node() then
+ log:debug('DIALPLAN_DEFAULT - node unauthorized - node_id: ', start_caller.node_id, ', domain: ', start_dialplan.domain);
+ start_dialplan:hangup(401, start_dialplan.domain);
+else
+ if not start_dialplan:auth_sip_account() then
+ local gateway = start_dialplan:auth_gateway()
-start_dialplan.database = database;
+ if gateway then
+ start_caller.gateway_name = gateway.name;
+ start_caller.gateway_id = gateway.id;
+ start_caller.from_gateway = true;
+ start_caller.gateway = gateway;
+ else
+ log:debug('AUTHENTICATION_REQUIRED_SIP_ACCOUNT - contact host: ' , start_caller.sip_contact_host, ', ip: ', start_caller.sip_network_ip, ', domain: ', start_dialplan.domain);
+ start_dialplan:hangup(407, start_dialplan.domain);
+ if database then
+ database:release();
+ end
+ return;
+ end
+ end
+end
-if start_caller.from_node and not start_dialplan:check_auth_node() then
+if start_caller.from_node then
log:debug('AUTHENTICATION_REQUIRED_NODE - node_id: ', start_caller.node_id, ', domain: ', start_dialplan.domain);
start_dialplan:hangup(407, start_dialplan.domain);
else
diff --git a/misc/freeswitch/scripts/event/call_history_save.lua b/misc/freeswitch/scripts/event/call_history_save.lua
index 057ca16..ba7a8f6 100644
--- a/misc/freeswitch/scripts/event/call_history_save.lua
+++ b/misc/freeswitch/scripts/event/call_history_save.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: call_history event handler class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/event/cdr_save.lua b/misc/freeswitch/scripts/event/cdr_save.lua
index ed53aa3..e7ac64a 100644
--- a/misc/freeswitch/scripts/event/cdr_save.lua
+++ b/misc/freeswitch/scripts/event/cdr_save.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: cdr event handler class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/event/event.lua b/misc/freeswitch/scripts/event/event.lua
index 8e67bc9..08d8bfe 100644
--- a/misc/freeswitch/scripts/event/event.lua
+++ b/misc/freeswitch/scripts/event/event.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: event manager class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -28,10 +28,8 @@ end
function EventManager.load_event_modules(self)
- local CONFIG_FILE_NAME = '/opt/freeswitch/scripts/ini/events.ini';
-
- require 'common.configuration_file'
- self.config = common.configuration_file.get(CONFIG_FILE_NAME);
+ require 'common.configuration_table'
+ self.config = common.configuration_table.get(self.database, 'events');
return self.config.modules;
end
@@ -40,7 +38,7 @@ end
function EventManager.load_event_handlers(self, event_modules)
event_handlers = {}
- for index, event_module_name in ipairs(event_modules) do
+ for event_module_name, index in pairs(event_modules) do
event_module = require('event.' .. event_module_name);
if event_module then
self.log:info('[event] EVENT_MANAGER - loading handler module: ', event_module_name);
diff --git a/misc/freeswitch/scripts/event/perimeter.lua b/misc/freeswitch/scripts/event/perimeter.lua
index 3babba6..5bbb032 100644
--- a/misc/freeswitch/scripts/event/perimeter.lua
+++ b/misc/freeswitch/scripts/event/perimeter.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: cdr event handler class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
@@ -40,7 +40,8 @@ end
function Perimeter.init(self)
- local config = common.configuration_file.get('/opt/freeswitch/scripts/ini/perimeter.ini');
+ require 'common.configuration_table';
+ local config = common.configuration_table.get(self.database, 'perimeter');
if config and config.general then
self.malicious_contact_count = tonumber(config.general.malicious_contact_count) or MALICIOUS_CONTACT_COUNT;
self.malicious_contact_time_span = tonumber(config.general.malicious_contact_time_span) or MALICIOUS_CONTACT_TIME_SPAN;
diff --git a/misc/freeswitch/scripts/event_manager.lua b/misc/freeswitch/scripts/event_manager.lua
index 0e3c0e0..4e78ccf 100644
--- a/misc/freeswitch/scripts/event_manager.lua
+++ b/misc/freeswitch/scripts/event_manager.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5.0 event handler
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
-- Set logger
@@ -17,10 +17,9 @@ if not database:connected() then
end
require "configuration.sip"
-local sip = configuration.sip.Sip:new{ log = log, database = database }
+local domains = configuration.sip.Sip:new{ log = log, database = database }:domains();
local domain = '127.0.0.1';
-local domains = sip:domains();
if domains[1] then
domain = domains[1]['host'];
else
diff --git a/misc/freeswitch/scripts/fax_daemon.lua b/misc/freeswitch/scripts/fax_daemon.lua
index cfe7c4e..6609fe6 100644
--- a/misc/freeswitch/scripts/fax_daemon.lua
+++ b/misc/freeswitch/scripts/fax_daemon.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5.0 fax daemon
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
local MAIN_LOOP_SLEEP_TIME = 30;
diff --git a/misc/freeswitch/scripts/ini/conferences.ini b/misc/freeswitch/scripts/ini/conferences.ini
deleted file mode 100644
index d8d0817..0000000
--- a/misc/freeswitch/scripts/ini/conferences.ini
+++ /dev/null
@@ -1,27 +0,0 @@
-; Gemeinschaft 5 conferences configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[parameters]
-caller-controls = speaker
-moderator-controls = moderator
-max-members = 100
-rate = 16000
-interval = 20
-energy-level = 300
-sound-prefix = /opt/freeswitch/sounds/en/us/callie
-muted-sound = conference/conf-muted.wav
-unmuted-sound = conference/conf-unmuted.wav
-alone-sound = conference/conf-alone.wav
-moh-sound = local_stream://moh
-enter-sound = tone_stream://%(200,0,500,600,700)
-exit-sound = tone_stream://%(500,0,300,200,100,50,25)
-kicked-sound = conference/conf-kicked.wav
-locked-sound = conference/conf-locked.wav
-is-locked-sound = conference/conf-is-locked.wav
-is-unlocked-sound = conference/conf-is-unlocked.wav
-pin-sound = conference/conf-pin.wav
-bad-pin-sound = conference/conf-bad-pin.wav
-caller-id-name = Conference
-caller-id-number =
-comfort-noise = true
diff --git a/misc/freeswitch/scripts/ini/database.ini b/misc/freeswitch/scripts/ini/database.ini
deleted file mode 100644
index 1652118..0000000
--- a/misc/freeswitch/scripts/ini/database.ini
+++ /dev/null
@@ -1,11 +0,0 @@
-; Gemeinschaft 5 database configuration
-; (c) AMOOMA GmbH 2012
-;
-
-driver = mysql
-
-[mysql]
-host = localhost
-database = gemeinschaft
-user = gemeinschaft
-password = gemeinschaft
diff --git a/misc/freeswitch/scripts/ini/dialplan.ini b/misc/freeswitch/scripts/ini/dialplan.ini
deleted file mode 100644
index aab8353..0000000
--- a/misc/freeswitch/scripts/ini/dialplan.ini
+++ /dev/null
@@ -1,14 +0,0 @@
-; Gemeinschaft 5 dialplan configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[parameters]
-node_id = 1
-phone_book_entry_image_url = http://192.168.0.150/uploads/phone_book_entry/image
-user_image_url = http://192.168.0.150/uploads/user/image
-ringtone_url = http://192.168.0.150
-ringback = %(2000,4000,440.0,480.0)
-tone_busy = %(500,500,480,620);loops=4
-
-phonebook_number_lookup = true
-geo_number_lookup = true \ No newline at end of file
diff --git a/misc/freeswitch/scripts/ini/events.ini b/misc/freeswitch/scripts/ini/events.ini
deleted file mode 100644
index e63eb73..0000000
--- a/misc/freeswitch/scripts/ini/events.ini
+++ /dev/null
@@ -1,8 +0,0 @@
-; Gemeinschaft 5 routing configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[modules]
-cdr_save
-call_history_save
-presence_update
diff --git a/misc/freeswitch/scripts/ini/gateways.ini.example b/misc/freeswitch/scripts/ini/gateways.ini.example
deleted file mode 100644
index b6ae018..0000000
--- a/misc/freeswitch/scripts/ini/gateways.ini.example
+++ /dev/null
@@ -1,23 +0,0 @@
-; Gemeinschaft 5 gateways configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[gateway1]
-profile = gemeinschaft
-name = gateway1
-username = gateway1
-realm = gemeinschaft
-password = freeswitch
-extension = default
-proxy = 192.168.0.1
-expire-seconds = 600
-register = true
-
-[gateway2]
-profile = gemeinschaft
-name = sipgate
-username = 1234567e0
-password = ABCdeF
-proxy = sipgate.com
-register = true
-extension = {sip_to_user}
diff --git a/misc/freeswitch/scripts/ini/perimeter.ini b/misc/freeswitch/scripts/ini/perimeter.ini
deleted file mode 100644
index ecbb032..0000000
--- a/misc/freeswitch/scripts/ini/perimeter.ini
+++ /dev/null
@@ -1,9 +0,0 @@
-; Gemeinschaft 5 perimeter defense configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[general]
-malicious_contact_count = 20
-malicious_contact_time_span = 2
-ban_futile = 5
-execute = sudo /usr/local/bin/ban_ip.sh {ip_address}
diff --git a/misc/freeswitch/scripts/ini/routes.ini b/misc/freeswitch/scripts/ini/routes.ini
deleted file mode 100644
index 1334e7b..0000000
--- a/misc/freeswitch/scripts/ini/routes.ini
+++ /dev/null
@@ -1,77 +0,0 @@
-; Gemeinschaft 5 routing configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[general]
-
-
-[prerouting]
-^%*0%*$ , f-li
-^%*0%*(%d+)#*$ , f-li-%1
-^%*0%*(%d+)%*(%d+)#*$ , f-li-%1-%2
-^#0#$ , f-lo
-^%*30#$ , f-clipon
-^#30#$ , f-clipoff
-^%*31#(%d+)$ , f-dclirof, f-%1
-^#31#(%d+)$ , f-dcliron-%1
-^%*43#$ , f-cwaon
-^#43#$ , f-cwaoff
-^#002#$ , f-cfoff
-^##002#$ , f-cfdel
-^%*21#$ , f-cfu
-^%*21%*(%d+)#$ , f-cfu-%1
-^%*%*21%*(%d+)#$ , f-cfu-%1
-^#21#$ , f-cfuoff
-^##21#$ , f-cfudel
-^%*61#$ , f-cfn
-^%*61%*(%d+)#$ , f-cfn-%1
-^%*%*61%*(%d+)#$ , f-cfn-%1
-^%*61%*(%d+)%*(%d+)#$ , f-cfn-%1-%2
-^%*%*61%*(%d+)%*(%d+)#$ , f-cfn-%1-%2
-^#61#$ , f-cfnoff
-^##61#$ , f-cfndel
-^%*62#$ , f-cfo
-^%*62%*(%d+)#$ , f-cfo-%1
-^%*%*62%*(%d+)#$ , f-cfo-%1
-^#62#$ , f-cfooff
-^##62#$ , f-cfodel
-^%*67#$ , f-cfb
-^%*67%*(%d+)#$ , f-cfb-%1
-^%*%*67%*(%d+)#$ , f-cfb-%1
-^#67#$ , f-cfboff
-^##67#$ , f-cfbdel
-^%*98$ , f-vmcheck
-^%*98#$ , f-vmcheck
-^%*98%*(%d+)#$ , f-vmcheck-%1
-^%*1337%*1%*1#$ , f-loaon
-^%*1337%*1%*0#$ , f-loaoff
-
-^00(%d+)$ , +%1
-^0(%d+)$ , +49%1
-
-
-[outbound]
-^%+(%d+)$ , class=gateway, endpoint=gateway1, group=users, %1
-^([1-9]%d+)$ , class=gateway, endpoint=gateway1, group=users, %1
-
-
-[failover]
-UNALLOCATED_NUMBER = true
-NORMAL_TEMPORARY_FAILURE = true
-
-
-[outbound_cid_number]
-
-
-[outbound_cid_name]
-
-
-[inbound]
-^00(%d+)$ , +%1
-^0(%d+)$ , +49%1
-
-[inbound_cid_number]
-^00(%d+)$ , +%1
-^0(%d+)$ , +49%1
-
-[inbound_cid_name]
diff --git a/misc/freeswitch/scripts/ini/sip_accounts.ini b/misc/freeswitch/scripts/ini/sip_accounts.ini
deleted file mode 100644
index 73a5fae..0000000
--- a/misc/freeswitch/scripts/ini/sip_accounts.ini
+++ /dev/null
@@ -1,10 +0,0 @@
-; Gemeinschaft 5 sip accounts default parameters
-; (c) AMOOMA GmbH 2012
-;
-
-[parameters]
-vm-enabled = true
-vm-email-all-messages = false
-vm-attach-file = false
-vm-mailto =
-
diff --git a/misc/freeswitch/scripts/ini/sofia.ini b/misc/freeswitch/scripts/ini/sofia.ini
deleted file mode 100644
index 5c99dbd..0000000
--- a/misc/freeswitch/scripts/ini/sofia.ini
+++ /dev/null
@@ -1,55 +0,0 @@
-; Gemeinschaft 5 sofia configuration file
-; (c) AMOOMA GmbH 2012
-;
-
-[profiles]
-gemeinschaft
-
-[parameters]
-log-level = 3
-debug-presence = 0
-
-[profile:gemeinschaft]
-user-agent-string = Gemeinschaft5
-debug = 0
-sip-trace = no
-log-auth-failures = false
-context = default
-rfc2833-pt = 101
-pass-rfc2833 = true
-sip-port = 5060
-dialplan = XML
-dtmf-duration = 2000
-rtp-timer-name = soft
-inbound-codec-prefs = PCMA,G7221@32000h,G7221@16000h,G722,PCMU,GSM
-outbound-codec-prefs = PCMA,G7221@32000h,G7221@16000h,G722,PCMU,GSM
-inbound-codec-negotiation = greedy
-ext-rtp-ip = auto-nat
-ext-sip-ip = auto-nat
-hold-music = local_stream://moh
-manage-presence = true
-tls = false
-tls-sip-port = 5061
-tls-cert-dir = /opt/freeswitch/conf/ssl
-accept-blind-reg = false
-accept-blind-auth = false
-nonce-ttl = 60
-disable-transcoding = false
-manual-redirect = true
-disable-transfer = false
-disable-register = false
-auth-calls = false
-inbound-reg-force-matching-username = true
-auth-all-packets = false
-rtp-timeout-sec = 300
-rtp-hold-timeout-sec = 1800
-force-subscription-expires = 3600
-sip-force-expires = 3000
-sip-expires-max-deviation = 600;
-challenge-realm = auto_from
-rtp-rewrite-timestamps = true
-inbound-use-callid-as-uuid = false
-outbound-use-callid-as-uuid = false
-context = default
-record-template = ${user_name}_${uuid}_${strftime(%Y-%m-%d-%H-%M-%S)}.wav
-odbc-dsn = gemeinschaft:gemeinschaft:gemeinschaft
diff --git a/misc/freeswitch/scripts/phones/phone.lua b/misc/freeswitch/scripts/phones/phone.lua
index bc2aa3d..856398b 100644
--- a/misc/freeswitch/scripts/phones/phone.lua
+++ b/misc/freeswitch/scripts/phones/phone.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: phone class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/phones/siemens.lua b/misc/freeswitch/scripts/phones/siemens.lua
index 71bb40a..ad2447a 100644
--- a/misc/freeswitch/scripts/phones/siemens.lua
+++ b/misc/freeswitch/scripts/phones/siemens.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: general siemens model class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/phones/snom.lua b/misc/freeswitch/scripts/phones/snom.lua
index 80d1fce..096ccb7 100644
--- a/misc/freeswitch/scripts/phones/snom.lua
+++ b/misc/freeswitch/scripts/phones/snom.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5 module: general snom model class
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
module(...,package.seeall)
diff --git a/misc/freeswitch/scripts/send_fax.lua b/misc/freeswitch/scripts/send_fax.lua
index 321a5b1..11cd1d7 100644
--- a/misc/freeswitch/scripts/send_fax.lua
+++ b/misc/freeswitch/scripts/send_fax.lua
@@ -1,5 +1,5 @@
-- Gemeinschaft 5.0
--- (c) AMOOMA GmbH 2012
+-- (c) AMOOMA GmbH 2012-2013
--
local FAX_FILE_PATH = "/opt/GS5/public/uploads/fax_document/tiff/";
@@ -80,36 +80,34 @@ local session = nil
if phone_number then
session = freeswitch.Session("[" .. table.concat(origination_variables, ",") .. "]loopback/" .. destination_number .. "/default");
else
- local owner_class = common.str.downcase(fax_account.record.fax_accountable_type);
-
- local caller = {}
- caller.caller_phone_numbers = phone_number_class:list_by_owner(fax_account.record.id, 'FaxAccount');
- caller.account = fax_account;
- caller.auth_account = fax_account;
- caller.caller_id_name = fax_account.record.station_id;
-
- if owner_class == 'user' then
- require 'dialplan.user'
- caller.auth_account.owner = dialplan.user.User:new{ log = log, database = database }:find_by_id(fax_account.record.fax_accountable_id);
- if caller.auth_account.owner then
- caller.auth_account.owner.groups = caller.auth_account.owner:list_groups();
- end
- elseif owner_class == 'tenant' then
- require 'dialplan.tenant'
- caller.auth_account.owner = dialplan.tenant.Tenant:new{ log = log, database = database }:find_by_id(fax_account.record.fax_accountable_id);
- end
+ local caller = {
+ destination_number = destination_number,
+ caller_id_name = fax_account.record.station_id,
+ account_type = 'faxaccount',
+ account_uuid = fax_account.uuid,
+ auth_account_type = 'faxaccount',
+ auth_account_uuid = fax_account.uuid,
+ }
- require 'common.configuration_file'
- local routing_table = common.configuration_file.get('/opt/freeswitch/scripts/ini/routes.ini');
- require 'dialplan.route'
- local routes = dialplan.route.Route:new{ log = log, database = database, routing_table = routing_table }:outbound(caller, destination_number);
+ require 'dialplan.dialplan'
+ local dialplan = dialplan.dialplan.Dialplan:new{ log = log, caller = caller, database = database };
+ local result = dialplan:retrieve_caller_data();
+
+ local dialplan_router = require('dialplan.router');
+ local routes = dialplan_router.Router:new{ log = log, database = database, caller = caller, variables = caller }:route_run('outbound');
+
+ if not routes or #routes == 0 then
+ log:notice('SWITCH - no route - number: ', destination_number);
+ return { continue = false, code = 404, phrase = 'No route' }
+ end
for index, route in ipairs(routes) do
- log:info('FAX_SEND - ', route.class, '=', route.endpoint, ', number: ', route.value);
- if route.class == 'gateway' then
+ log:info('FAX_SEND - ', route.type, '=', route.id, '/', route.gateway,', number: ', route.destination_number);
+ if route.type == 'gateway' then
table.insert(origination_variables, "origination_caller_id_number='" .. (route.caller_id_number or caller.caller_phone_numbers[1]) .. "'");
table.insert(origination_variables, "origination_caller_id_name='" .. (route.caller_id_name or fax_account.record.station_id) .. "'");
- session = freeswitch.Session('[' .. table.concat(origination_variables, ',') .. ']sofia/gateway/' .. route.endpoint .. '/' .. route.value);
+ session = freeswitch.Session('[' .. table.concat(origination_variables, ',') .. ']sofia/gateway/' .. route.gateway .. '/' .. route.destination_number);
+ log:notice('SESSION: ', session);
break;
end
end
diff --git a/misc/mon_ami/asterisk.py b/misc/mon_ami/asterisk.py
index ffcff06..3406c5b 100644
--- a/misc/mon_ami/asterisk.py
+++ b/misc/mon_ami/asterisk.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
# Asterisk AMI client connector
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from threading import Thread, Lock
from log import ldebug, linfo, lwarn, lerror, lcritic
diff --git a/misc/mon_ami/freeswitch.py b/misc/mon_ami/freeswitch.py
index eab9bb6..218b7db 100644
--- a/misc/mon_ami/freeswitch.py
+++ b/misc/mon_ami/freeswitch.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface server
# FreeSWITCH event socket interface
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from threading import Thread, Lock
from log import ldebug, linfo, lwarn, lerror, lcritic
diff --git a/misc/mon_ami/helper.py b/misc/mon_ami/helper.py
index bf286de..8e665a4 100644
--- a/misc/mon_ami/helper.py
+++ b/misc/mon_ami/helper.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface server
# helper functions
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
def to_hash(message):
diff --git a/misc/mon_ami/log.py b/misc/mon_ami/log.py
index 92709ad..e89a53f 100644
--- a/misc/mon_ami/log.py
+++ b/misc/mon_ami/log.py
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Log library
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
import logging
diff --git a/misc/mon_ami/mon-ami b/misc/mon_ami/mon-ami
deleted file mode 100755
index a630140..0000000
--- a/misc/mon_ami/mon-ami
+++ /dev/null
@@ -1,58 +0,0 @@
-#!/bin/sh
-
-#####################################################################
-# MonAMI Asterisk Manger Interface Emulator
-# Start Script
-# (c) AMOOMA GmbH 2012
-#####################################################################
-
-### BEGIN INIT INFO
-# Provides: mon_ami
-# Required-Start: freeswitch
-# Required-Stop: freeswitch
-# Default-Start: 2 3 4 5
-# Default-Stop: 0 1 6
-# Short-Description: MonAMI Asterisk Manger Interface Emulator
-# Description:
-#
-### END INIT INFO
-
-DAEMON=/opt/GS5/misc/mon_ami/mon_ami
-EXECUTABLE=`basename 'mon_ami'`
-DESC="MonAMI Asterisk Manger Interface Emulator"
-ARGS="--log-file=/var/log/mon_ami.log"
-
-if ! [ -x $DAEMON ] ; then
- echo "ERROR: $DAEMON not found"
- exit 1
-fi
-
-case "$1" in
- start)
- echo -n "Starting $DESC: "
- start-stop-daemon --start --pidfile /var/run/$EXECUTABLE.pid \
- --make-pidfile --background --startas $DAEMON -- $ARGS
- echo "$EXECUTABLE."
- ;;
-
- stop)
- echo -n "Stopping $DESC: "
- start-stop-daemon --stop --quiet --oknodo --retry=TERM/30/KILL/5 \
- --pidfile /var/run/$EXECUTABLE.pid
- rm -f /var/run/$NAME.pid
- echo "$EXECUTABLE."
- ;;
-
- reload|restart|force-reload)
- $0 stop
- sleep 2
- $0 start
- ;;
-
- *)
- echo "Usage: $0 {start|stop|restart|reload|force-reload}" >&2
- exit 1
- ;;
-esac
-
-exit 0
diff --git a/misc/mon_ami/mon_ami b/misc/mon_ami/mon_ami
index a212cfe..0e8ce50 100755
--- a/misc/mon_ami/mon_ami
+++ b/misc/mon_ami/mon_ami
@@ -1,7 +1,7 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from mon_ami_main import main
from sys import exit
diff --git a/misc/mon_ami/mon_ami_handler.py b/misc/mon_ami/mon_ami_handler.py
index 59e9225..015f547 100644
--- a/misc/mon_ami/mon_ami_handler.py
+++ b/misc/mon_ami/mon_ami_handler.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
# Asterisk AMI Emulator Handler Process
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from threading import Thread
from log import ldebug, linfo, lwarn, lerror, lcritic
diff --git a/misc/mon_ami/mon_ami_main.py b/misc/mon_ami/mon_ami_main.py
index 13dd4bb..72220e5 100644
--- a/misc/mon_ami/mon_ami_main.py
+++ b/misc/mon_ami/mon_ami_main.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
# Main Programm
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from log import ldebug, linfo, lwarn, lerror, lcritic, setup_log
from time import sleep
diff --git a/misc/mon_ami/mon_ami_server.py b/misc/mon_ami/mon_ami_server.py
index 68e72c8..d3d7c0f 100644
--- a/misc/mon_ami/mon_ami_server.py
+++ b/misc/mon_ami/mon_ami_server.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
# Asterisk AMI Emulator server thread
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
from threading import Thread
from log import ldebug, linfo, lwarn, lerror, lcritic
diff --git a/misc/mon_ami/tcp_server.py b/misc/mon_ami/tcp_server.py
index 5536282..5faa9ea 100644
--- a/misc/mon_ami/tcp_server.py
+++ b/misc/mon_ami/tcp_server.py
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# MonAMI Asterisk Manger Interface Server
# TCP Server
-# (c) AMOOMA GmbH 2012
+# (c) AMOOMA GmbH 2012-2013
import socket
from traceback import format_exc
diff --git a/misc/nginx/nginx.conf b/misc/nginx/nginx.conf
deleted file mode 100644
index c1c1a39..0000000
--- a/misc/nginx/nginx.conf
+++ /dev/null
@@ -1,81 +0,0 @@
-
-user www-data;
-worker_processes 1;
-
-#error_log logs/error.log;
-#error_log logs/error.log notice;
-#error_log logs/error.log info;
-
-#pid logs/nginx.pid;
-
-
-events {
- worker_connections 1024;
-}
-
-
-http {
- passenger_root /usr/local/rvm/gems/ruby-1.9.2-p290/gems/passenger-3.0.11;
- passenger_ruby /usr/local/rvm/wrappers/ruby-1.9.2-p290/ruby;
-
- include mime.types;
- default_type application/octet-stream;
-
- #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
- # '$status $body_bytes_sent "$http_referer" '
- # '"$http_user_agent" "$http_x_forwarded_for"';
-
- #access_log logs/access.log main;
-
- sendfile on;
- #tcp_nopush on;
-
- #keepalive_timeout 0;
- keepalive_timeout 65;
-
- #gzip on;
-
- server {
- listen 80;
- server_name localhost;
- root /opt/GS5/public;
- passenger_enabled on;
- }
-
- # another virtual host using mix of IP-, name-, and port-based configuration
- #
- #server {
- # listen 8000;
- # listen somename:8080;
- # server_name somename alias another.alias;
-
- # location / {
- # root html;
- # index index.html index.htm;
- # }
- #}
-
-
- # HTTPS server
- #
- #server {
- # listen 443;
- # server_name localhost;
-
- # ssl on;
- # ssl_certificate cert.pem;
- # ssl_certificate_key cert.key;
-
- # ssl_session_timeout 5m;
-
- # ssl_protocols SSLv2 SSLv3 TLSv1;
- # ssl_ciphers HIGH:!aNULL:!MD5;
- # ssl_prefer_server_ciphers on;
-
- # location / {
- # root html;
- # index index.html index.htm;
- # }
- #}
-
-}
diff --git a/script/fax_new b/script/fax_new
index 8015da8..125632c 100755
--- a/script/fax_new
+++ b/script/fax_new
@@ -63,7 +63,7 @@ system "tiff2pdf \\
-o \"#{pdf_file}\" \\
-p #{paper_size} \\
-a \"#{fax_arguments[:remote_station_id]}\" \\
- -c \"AMOOMA Gemeinschaft version #{GEMEINSCHAFT_VERSION}\" \\
+ -c \"AMOOMA Gemeinschaft version #{GsParameter.get('GEMEINSCHAFT_VERSION')}\" \\
-t \"#{fax_arguments[:remote_station_id]}\" \"#{tiff_file}\""
if !File.exists?( pdf_file )
diff --git a/script/fax_new.sh b/script/fax_new.sh
deleted file mode 100755
index 3c98d41..0000000
--- a/script/fax_new.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/bash
-cd /opt/GS5/script/
-source /usr/local/rvm/scripts/rvm
-/opt/GS5/script/fax_new "$@"
diff --git a/script/logout_phones.sh b/script/logout_phones.sh
deleted file mode 100755
index 2a1a54e..0000000
--- a/script/logout_phones.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/bash
-cd /opt/GS5/script/
-source /usr/local/rvm/scripts/rvm
-/opt/GS5/script/logout_phones $@
diff --git a/script/voicemail_new.sh b/script/voicemail_new.sh
deleted file mode 100755
index dcb29f5..0000000
--- a/script/voicemail_new.sh
+++ /dev/null
@@ -1,4 +0,0 @@
-#! /bin/bash
-
-source /usr/local/rvm/scripts/rvm
-/opt/GS5/script/voicemail_new $@
diff --git a/test/factories/area_codes.rb b/test/factories/area_codes.rb
index 87b2271..3ed894d 100644
--- a/test/factories/area_codes.rb
+++ b/test/factories/area_codes.rb
@@ -1,7 +1,9 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :area_code do |f|
- f.sequence(:name) { |n| "AreaCode #{n}" }
- f.sequence(:area_code) { |n| "#{n}" }
- f.association :country
+FactoryGirl.define do
+ factory :area_code do
+ sequence(:name) { |n| "AreaCode #{n}" }
+ sequence(:area_code) { |n| "#{n}" }
+ association :country
+ end
end \ No newline at end of file
diff --git a/test/factories/call_forwards.rb b/test/factories/call_forwards.rb
index d275e9d..bdb899e 100644
--- a/test/factories/call_forwards.rb
+++ b/test/factories/call_forwards.rb
@@ -1,16 +1,18 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :call_forward do |f|
- f.association :phone_number
- #OPTIMIZE Make sure that the phone_number's phone_numberable
- # isn't a phone_book_entry but a sip_account.
- #f.sequence( :call_forward_case_id ) { |n| CallForwardCase.where(:value => "always").first.id }
- #f.association :call_forward_case
- f.sequence( :call_forward_case_id ) { |n| 1 }
- f.sequence( :destination ) { |n| "20#{n}" }
- f.sequence( :to_voicemail ) { |n| false }
- f.sequence( :timeout ) { |n| nil }
- f.sequence( :source ) { |n| nil }
- f.sequence( :depth ) { |n| 5 }
- f.sequence( :active ) { |n| false }
+FactoryGirl.define do
+ factory :call_forward do
+ association :phone_number
+ #OPTIMIZE Make sure that the phone_number's phone_numberable
+ # isn't a phone_book_entry but a sip_account.
+ #f.sequence( :call_forward_case_id ) { |n| CallForwardCase.where(:value => "always").first.id }
+ #f.association :call_forward_case
+ sequence( :call_forward_case_id ) { |n| 1 }
+ sequence( :destination ) { |n| "20#{n}" }
+ sequence( :to_voicemail ) { |n| false }
+ sequence( :timeout ) { |n| nil }
+ sequence( :source ) { |n| nil }
+ sequence( :depth ) { |n| 5 }
+ sequence( :active ) { |n| false }
+ end
end
diff --git a/test/factories/conference_invitees.rb b/test/factories/conference_invitees.rb
index 4e1eb68..54fa53a 100644
--- a/test/factories/conference_invitees.rb
+++ b/test/factories/conference_invitees.rb
@@ -1,8 +1,10 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :conference_invitee do |f|
- f.phone_number { Factory.build(:phone_number) }
- f.association :conference
- f.speaker true
- f.moderator false
+FactoryGirl.define do
+ factory :conference_invitee do
+ phone_number { FactoryGirl.build(:phone_number) }
+ association :conference
+ speaker true
+ moderator false
+ end
end \ No newline at end of file
diff --git a/test/factories/conferences.rb b/test/factories/conferences.rb
index 3c49a7a..7a563b7 100644
--- a/test/factories/conferences.rb
+++ b/test/factories/conferences.rb
@@ -1,8 +1,10 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :conference do |f|
- f.sequence(:name) { |n| "Conference room #{n}" }
- f.open_for_anybody true
- f.association :conferenceable, :factory => :tenant
- f.max_members 10
+FactoryGirl.define do
+ factory :conference do
+ sequence(:name) { |n| "Conference room #{n}" }
+ open_for_anybody true
+ association :conferenceable, :factory => :tenant
+ max_members 10
+ end
end \ No newline at end of file
diff --git a/test/factories/countries.rb b/test/factories/countries.rb
index cc3fc88..99caab5 100644
--- a/test/factories/countries.rb
+++ b/test/factories/countries.rb
@@ -1,8 +1,10 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :country do |f|
- f.sequence(:name) { |n| "Country #{n}" }
- f.sequence(:country_code) { |n| "#{n}" }
- f.sequence(:international_call_prefix) { |n| "#{n}" }
- f.sequence(:trunk_prefix) { |n| "#{n}" }
+FactoryGirl.define do
+ factory :country do
+ sequence(:name) { |n| "Country #{n}" }
+ sequence(:country_code) { |n| "#{n}" }
+ sequence(:international_call_prefix) { |n| "#{n}" }
+ sequence(:trunk_prefix) { |n| "#{n}" }
+ end
end \ No newline at end of file
diff --git a/test/factories/gemeinschaft_setups.rb b/test/factories/gemeinschaft_setups.rb
index ed69bc3..a2c0f72 100644
--- a/test/factories/gemeinschaft_setups.rb
+++ b/test/factories/gemeinschaft_setups.rb
@@ -1,8 +1,10 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :gemeinschaft_setup do |f|
- f.association :user
- f.association :sip_domain
- f.association :country
- f.association :language
+FactoryGirl.define do
+ factory :gemeinschaft_setup do
+ association :user
+ association :sip_domain
+ association :country
+ association :language
+ end
end \ No newline at end of file
diff --git a/test/factories/languages.rb b/test/factories/languages.rb
index 29d2ece..a8ecace 100644
--- a/test/factories/languages.rb
+++ b/test/factories/languages.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :language do |f|
- f.name 'Deutsch'
- f.code 'de'
+FactoryGirl.define do
+ factory :language do
+ name 'Deutsch'
+ code 'de'
+ end
end \ No newline at end of file
diff --git a/test/factories/manufacturers.rb b/test/factories/manufacturers.rb
index f091dd2..e211fc6 100644
--- a/test/factories/manufacturers.rb
+++ b/test/factories/manufacturers.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :manufacturer do |f|
- f.sequence(:name) { |n| "#{n}. manufacturer" }
- f.sequence(:ieee_name) { |n| "#{n}. ieee" }
+FactoryGirl.define do
+ factory :manufacturer do
+ sequence(:name) { |n| "#{n}. manufacturer" }
+ sequence(:ieee_name) { |n| "#{n}. ieee" }
+ end
end \ No newline at end of file
diff --git a/test/factories/ouis.rb b/test/factories/ouis.rb
index 3a90fd4..f99f02b 100644
--- a/test/factories/ouis.rb
+++ b/test/factories/ouis.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :oui do |f|
- f.association :manufacturer
- f.sequence(:value) { |n| (n + 11184810).to_s(16).upcase }
+FactoryGirl.define do
+ factory :oui do
+ association :manufacturer
+ sequence(:value) { |n| (n + 11184810).to_s(16).upcase }
+ end
end \ No newline at end of file
diff --git a/test/factories/phone_book_entries.rb b/test/factories/phone_book_entries.rb
index 7427886..8e1b535 100644
--- a/test/factories/phone_book_entries.rb
+++ b/test/factories/phone_book_entries.rb
@@ -1,7 +1,9 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone_book_entry do |f|
- f.sequence(:last_name) { |n| "Lastname #{n}" }
- f.sequence(:is_male) { |n| true }
- f.association :phone_book
+FactoryGirl.define do
+ factory :phone_book_entry do
+ sequence(:last_name) { |n| "Lastname #{n}" }
+ sequence(:is_male) { |n| true }
+ association :phone_book
+ end
end
diff --git a/test/factories/phone_books.rb b/test/factories/phone_books.rb
index 4aa8d07..80e2a06 100644
--- a/test/factories/phone_books.rb
+++ b/test/factories/phone_books.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone_book do |f|
- f.sequence(:name) { |n| "Phone book #{n}" }
- f.association :phone_bookable, :factory => :user
+FactoryGirl.define do
+ factory :phone_book do
+ sequence(:name) { |n| "Phone book #{n}" }
+ association :phone_bookable, :factory => :user
+ end
end
diff --git a/test/factories/phone_models.rb b/test/factories/phone_models.rb
index 8e6a50f..28b8802 100644
--- a/test/factories/phone_models.rb
+++ b/test/factories/phone_models.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone_model do |f|
- f.sequence(:name) { |n| "Phone Model #{n}" }
- f.association :manufacturer
+FactoryGirl.define do
+ factory :phone_model do
+ sequence(:name) { |n| "Phone Model #{n}" }
+ association :manufacturer
+ end
end
diff --git a/test/factories/phone_number_ranges.rb b/test/factories/phone_number_ranges.rb
index cb2f7ee..306fdee 100644
--- a/test/factories/phone_number_ranges.rb
+++ b/test/factories/phone_number_ranges.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone_number_range do |f|
- f.name INTERNAL_EXTENSIONS
- f.association :phone_number_rangeable, :factory => :tenant
+FactoryGirl.define do
+ factory :phone_number_range do
+ name 'internal_extensions'
+ association :phone_number_rangeable, :factory => :tenant
+ end
end
diff --git a/test/factories/phone_numbers.rb b/test/factories/phone_numbers.rb
index 74b43cc..3b25938 100644
--- a/test/factories/phone_numbers.rb
+++ b/test/factories/phone_numbers.rb
@@ -1,7 +1,9 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone_number do |f|
- f.sequence(:name) { |n| "Name #{n}" }
- f.sequence(:number) { |n| "(0)30 227 #{n}" }
- f.association :phone_numberable, :factory => :phone_book_entry
+FactoryGirl.define do
+ factory :phone_number do
+ sequence(:name) { |n| "Name #{n}" }
+ sequence(:number) { |n| "(0)30 227 #{n}" }
+ association :phone_numberable, :factory => :phone_book_entry
+ end
end \ No newline at end of file
diff --git a/test/factories/phones.rb b/test/factories/phones.rb
index 646d548..af0b37a 100644
--- a/test/factories/phones.rb
+++ b/test/factories/phones.rb
@@ -1,15 +1,17 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :phone do |f|
- f.sequence(:mac_address) { |n| ('%06d' % n).to_s + ('%06d' % n).to_s }
- f.association :phone_model
- f.association :phoneable, :factory => :tenant
+FactoryGirl.define do
+ factory :phone do |f|
+ f.sequence(:mac_address) { |n| ('%06d' % n).to_s + ('%06d' % n).to_s }
+ f.association :phone_model
+ f.association :phoneable, :factory => :tenant
- # We have to make sure that the OUI is created as well.
- f.after_build do |instance|
- Factory.create(:oui,
- :manufacturer => instance.phone_model.manufacturer,
- :value => instance.mac_address.slice(0, 6)
- )
+ # We have to make sure that the OUI is created as well.
+ f.after_build do |instance|
+ FactoryGirl.create(:oui,
+ :manufacturer => instance.phone_model.manufacturer,
+ :value => instance.mac_address.slice(0, 6)
+ )
+ end
end
end \ No newline at end of file
diff --git a/test/factories/sip_accounts.rb b/test/factories/sip_accounts.rb
index 2f91717..a21fa27 100644
--- a/test/factories/sip_accounts.rb
+++ b/test/factories/sip_accounts.rb
@@ -1,17 +1,19 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :sip_account do |f|
- f.association :sip_accountable, :factory => :user
- f.sequence(:auth_name) {|n| "auth_name#{n}" }
- f.sequence(:caller_name) {|n| "Foo Account #{n}" }
- f.sequence(:password) {|n| "12345678" }
-
- f.after_build do |sip_account|
- if sip_account.tenant_id.blank?
- tenant = sip_account.create_tenant(FactoryGirl.build(:tenant).attributes)
- sip_domain = tenant.create_sip_domain(FactoryGirl.build(:sip_domain).attributes)
- sip_account.tenant.tenant_memberships.create(:user_id => sip_account.sip_accountable.id)
- sip_account.tenant_id = tenant.id
+FactoryGirl.define do
+ factory :sip_account do |f|
+ f.association :sip_accountable, :factory => :user
+ f.sequence(:auth_name) {|n| "auth_name#{n}" }
+ f.sequence(:caller_name) {|n| "Foo Account #{n}" }
+ f.sequence(:password) {|n| "12345678" }
+
+ f.after_build do |sip_account|
+ if sip_account.tenant_id.blank?
+ tenant = sip_account.create_tenant(FactoryGirl.build(:tenant).attributes)
+ sip_domain = tenant.create_sip_domain(FactoryGirl.build(:sip_domain).attributes)
+ sip_account.tenant.tenant_memberships.create(:user_id => sip_account.sip_accountable.id)
+ sip_account.tenant_id = tenant.id
+ end
end
end
end
diff --git a/test/factories/sip_domains.rb b/test/factories/sip_domains.rb
index 347b6a6..442f270 100644
--- a/test/factories/sip_domains.rb
+++ b/test/factories/sip_domains.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :sip_domain do |f|
- f.sequence(:host ) {|n| "host#{n}.localdomain" }
- f.sequence(:realm ) {|n| "host#{n}.localdomain" }
+FactoryGirl.define do
+ factory :sip_domain do
+ sequence(:host ) {|n| "host#{n}.localdomain" }
+ sequence(:realm ) {|n| "host#{n}.localdomain" }
+ end
end
diff --git a/test/factories/tenant_memberships.rb b/test/factories/tenant_memberships.rb
index ee52367..38c4cb8 100644
--- a/test/factories/tenant_memberships.rb
+++ b/test/factories/tenant_memberships.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :tenant_membership do |f|
- f.association :user
- f.association :tenant
+FactoryGirl.define do
+ factory :tenant_membership do
+ association :user
+ association :tenant
+ end
end \ No newline at end of file
diff --git a/test/factories/tenants.rb b/test/factories/tenants.rb
index 9a62e93..fc85e88 100644
--- a/test/factories/tenants.rb
+++ b/test/factories/tenants.rb
@@ -1,8 +1,9 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :tenant do |f|
- f.sequence(:name) { |n| "Tenant #{n}" }
- f.association :country
- f.association :language
-# f.association :sip_domain
+FactoryGirl.define do
+ factory :tenant do
+ sequence(:name) { |n| "Tenant #{n}" }
+ association :country
+ association :language
+ end
end
diff --git a/test/factories/user_group_memberships.rb b/test/factories/user_group_memberships.rb
index 7904f2f..8dc74f0 100644
--- a/test/factories/user_group_memberships.rb
+++ b/test/factories/user_group_memberships.rb
@@ -1,14 +1,16 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :user_group_membership do |f|
- f.association :user_group
- f.association :user
-
- # Make sure that the User is a member of the Tenant.
- f.after_build do |instance|
- Factory.create(:tenant_membership,
- :tenant_id => instance.user_group.tenant.id,
- :user_id => instance.user.id
- )
+FactoryGirl.define do
+ factory :user_group_membership do |f|
+ f.association :user_group
+ f.association :user
+
+ # Make sure that the User is a member of the Tenant.
+ f.after_build do |instance|
+ FactoryGirl.create(:tenant_membership,
+ :tenant_id => instance.user_group.tenant.id,
+ :user_id => instance.user.id
+ )
+ end
end
end \ No newline at end of file
diff --git a/test/factories/user_groups.rb b/test/factories/user_groups.rb
index 9a448ec..c777d95 100644
--- a/test/factories/user_groups.rb
+++ b/test/factories/user_groups.rb
@@ -1,6 +1,8 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :user_group do |f|
- f.sequence(:name) { |n| "UserGroup #{n}" }
- f.association :tenant
+FactoryGirl.define do
+ factory :user_group do
+ sequence(:name) { |n| "UserGroup #{n}" }
+ association :tenant
+ end
end \ No newline at end of file
diff --git a/test/factories/users.rb b/test/factories/users.rb
index 3d53141..a84b41d 100644
--- a/test/factories/users.rb
+++ b/test/factories/users.rb
@@ -1,11 +1,13 @@
# Read about factories at http://github.com/thoughtbot/factory_girl
-Factory.define :user do |f|
- f.sequence(:user_name) { |n| "User #{n}" }
- f.sequence(:first_name) { |n| "John #{n}" }
- f.sequence(:last_name) { |n| "Smith #{n}" }
- f.sequence(:email) { |n| "john.smith#{n}@company.com" }
- f.sequence(:password) { |n| "Testpassword#{n}" }
- f.sequence(:password_confirmation) { |n| "Testpassword#{n}" }
- f.association :language
+FactoryGirl.define do
+ factory :user do
+ sequence(:user_name) { |n| "User #{n}" }
+ sequence(:first_name) { |n| "John #{n}" }
+ sequence(:last_name) { |n| "Smith #{n}" }
+ sequence(:email) { |n| "john.smith#{n}@company.com" }
+ sequence(:password) { |n| "Testpassword#{n}" }
+ sequence(:password_confirmation) { |n| "Testpassword#{n}" }
+ association :language
+ end
end \ No newline at end of file
diff --git a/test/functional/call_forwards_controller_test.rb b/test/functional/call_forwards_controller_test.rb
index 0993623..da8e6c9 100644
--- a/test/functional/call_forwards_controller_test.rb
+++ b/test/functional/call_forwards_controller_test.rb
@@ -3,27 +3,27 @@ require 'test_helper'
class CallForwardsControllerTest < ActionController::TestCase
setup do
- @user = Factory.create(:user)
+ @user = FactoryGirl.create(:user)
- #@tenant = Factory.create(:tenant)
+ #@tenant = FactoryGirl.create(:tenant)
#@tenant.tenant_memberships.create(:user_id => @user.id)
#@user.update_attributes!(:current_tenant_id => @tenant.id)
- @sip_account = Factory.create(
+ @sip_account = FactoryGirl.create(
:sip_account,
:sip_accountable => @user,
)
@user.sip_accounts << @sip_account
@sip_account = @user.sip_accounts.last
- @phone_number = Factory.create(
+ @phone_number = FactoryGirl.create(
:phone_number,
:phone_numberable => @sip_account,
)
@sip_account.phone_numbers << @phone_number
@phone_number = @sip_account.phone_numbers.last
- @call_forward = Factory.create(
+ @call_forward = FactoryGirl.create(
:call_forward,
:phone_number => @phone_number,
)
@@ -50,7 +50,7 @@ class CallForwardsControllerTest < ActionController::TestCase
# assert_difference('CallForward.count') do
# post :create,
# :phone_number_id => @phone_number.to_param,
-# :call_forward => Factory.attributes_for(
+# :call_forward => FactoryGirl.attributes_for(
# :call_forward
# )
# end
diff --git a/test/functional/call_routes_controller_test.rb b/test/functional/call_routes_controller_test.rb
new file mode 100644
index 0000000..77c0b2a
--- /dev/null
+++ b/test/functional/call_routes_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class CallRoutesControllerTest < ActionController::TestCase
+ setup do
+ @call_route = call_routes(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:call_routes)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create call_route" do
+ assert_difference('CallRoute.count') do
+ post :create, call_route: @call_route.attributes
+ end
+
+ assert_redirected_to call_route_path(assigns(:call_route))
+ end
+
+ test "should show call_route" do
+ get :show, id: @call_route.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @call_route.to_param
+ assert_response :success
+ end
+
+ test "should update call_route" do
+ put :update, id: @call_route.to_param, call_route: @call_route.attributes
+ assert_redirected_to call_route_path(assigns(:call_route))
+ end
+
+ test "should destroy call_route" do
+ assert_difference('CallRoute.count', -1) do
+ delete :destroy, id: @call_route.to_param
+ end
+
+ assert_redirected_to call_routes_path
+ end
+end
diff --git a/test/functional/conference_invitees_controller_test.rb b/test/functional/conference_invitees_controller_test.rb
index 72d2e2c..8ac5479 100644
--- a/test/functional/conference_invitees_controller_test.rb
+++ b/test/functional/conference_invitees_controller_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class ConferenceInviteesControllerTest < ActionController::TestCase
setup do
- @conference_invitee = Factory.create(:conference_invitee)
+ @conference_invitee = FactoryGirl.create(:conference_invitee)
end
# test "should get index" do
diff --git a/test/functional/conferences_controller_test.rb b/test/functional/conferences_controller_test.rb
index 954838b..0f2d007 100644
--- a/test/functional/conferences_controller_test.rb
+++ b/test/functional/conferences_controller_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class ConferencesControllerTest < ActionController::TestCase
setup do
- @conference = Factory.create(:conference)
+ @conference = FactoryGirl.create(:conference)
end
# test "should get index" do
diff --git a/test/functional/gateway_parameters_controller_test.rb b/test/functional/gateway_parameters_controller_test.rb
new file mode 100644
index 0000000..6f6ce40
--- /dev/null
+++ b/test/functional/gateway_parameters_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class GatewayParametersControllerTest < ActionController::TestCase
+ setup do
+ @gateway_parameter = gateway_parameters(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:gateway_parameters)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create gateway_parameter" do
+ assert_difference('GatewayParameter.count') do
+ post :create, gateway_parameter: @gateway_parameter.attributes
+ end
+
+ assert_redirected_to gateway_parameter_path(assigns(:gateway_parameter))
+ end
+
+ test "should show gateway_parameter" do
+ get :show, id: @gateway_parameter.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @gateway_parameter.to_param
+ assert_response :success
+ end
+
+ test "should update gateway_parameter" do
+ put :update, id: @gateway_parameter.to_param, gateway_parameter: @gateway_parameter.attributes
+ assert_redirected_to gateway_parameter_path(assigns(:gateway_parameter))
+ end
+
+ test "should destroy gateway_parameter" do
+ assert_difference('GatewayParameter.count', -1) do
+ delete :destroy, id: @gateway_parameter.to_param
+ end
+
+ assert_redirected_to gateway_parameters_path
+ end
+end
diff --git a/test/functional/gateway_settings_controller_test.rb b/test/functional/gateway_settings_controller_test.rb
new file mode 100644
index 0000000..c416528
--- /dev/null
+++ b/test/functional/gateway_settings_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class GatewaySettingsControllerTest < ActionController::TestCase
+ setup do
+ @gateway_setting = gateway_settings(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:gateway_settings)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create gateway_setting" do
+ assert_difference('GatewaySetting.count') do
+ post :create, gateway_setting: @gateway_setting.attributes
+ end
+
+ assert_redirected_to gateway_setting_path(assigns(:gateway_setting))
+ end
+
+ test "should show gateway_setting" do
+ get :show, id: @gateway_setting.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @gateway_setting.to_param
+ assert_response :success
+ end
+
+ test "should update gateway_setting" do
+ put :update, id: @gateway_setting.to_param, gateway_setting: @gateway_setting.attributes
+ assert_redirected_to gateway_setting_path(assigns(:gateway_setting))
+ end
+
+ test "should destroy gateway_setting" do
+ assert_difference('GatewaySetting.count', -1) do
+ delete :destroy, id: @gateway_setting.to_param
+ end
+
+ assert_redirected_to gateway_settings_path
+ end
+end
diff --git a/test/functional/gateways_controller_test.rb b/test/functional/gateways_controller_test.rb
new file mode 100644
index 0000000..e0928dd
--- /dev/null
+++ b/test/functional/gateways_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class GatewaysControllerTest < ActionController::TestCase
+ setup do
+ @gateway = gateways(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:gateways)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create gateway" do
+ assert_difference('Gateway.count') do
+ post :create, gateway: @gateway.attributes
+ end
+
+ assert_redirected_to gateway_path(assigns(:gateway))
+ end
+
+ test "should show gateway" do
+ get :show, id: @gateway.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @gateway.to_param
+ assert_response :success
+ end
+
+ test "should update gateway" do
+ put :update, id: @gateway.to_param, gateway: @gateway.attributes
+ assert_redirected_to gateway_path(assigns(:gateway))
+ end
+
+ test "should destroy gateway" do
+ assert_difference('Gateway.count', -1) do
+ delete :destroy, id: @gateway.to_param
+ end
+
+ assert_redirected_to gateways_path
+ end
+end
diff --git a/test/functional/gemeinschaft_setups_controller_test.rb b/test/functional/gemeinschaft_setups_controller_test.rb
index b23a878..5e6cadf 100644
--- a/test/functional/gemeinschaft_setups_controller_test.rb
+++ b/test/functional/gemeinschaft_setups_controller_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class GemeinschaftSetupsControllerTest < ActionController::TestCase
setup do
- @gemeinschaft_setup = Factory.build(:gemeinschaft_setup)
+ @gemeinschaft_setup = FactoryGirl.build(:gemeinschaft_setup)
end
# test "should get index" do
@@ -20,7 +20,7 @@ class GemeinschaftSetupsControllerTest < ActionController::TestCase
# test "should create gemeinschaft_setup" do
# assert_difference('GemeinschaftSetup.count') do
# post :create,
-# gemeinschaft_setup: Factory.attributes_for(:gemeinschaft_setup)
+# gemeinschaft_setup: FactoryGirl.attributes_for(:gemeinschaft_setup)
# end
# assert_redirected_to gemeinschaft_setup_path(assigns(:gemeinschaft_setup))
# end
diff --git a/test/functional/gs_parameters_controller_test.rb b/test/functional/gs_parameters_controller_test.rb
new file mode 100644
index 0000000..a0e498a
--- /dev/null
+++ b/test/functional/gs_parameters_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class GsParametersControllerTest < ActionController::TestCase
+ setup do
+ @gs_parameter = gs_parameters(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:gs_parameters)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create gs_parameter" do
+ assert_difference('GsParameter.count') do
+ post :create, gs_parameter: @gs_parameter.attributes
+ end
+
+ assert_redirected_to gs_parameter_path(assigns(:gs_parameter))
+ end
+
+ test "should show gs_parameter" do
+ get :show, id: @gs_parameter.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @gs_parameter.to_param
+ assert_response :success
+ end
+
+ test "should update gs_parameter" do
+ put :update, id: @gs_parameter.to_param, gs_parameter: @gs_parameter.attributes
+ assert_redirected_to gs_parameter_path(assigns(:gs_parameter))
+ end
+
+ test "should destroy gs_parameter" do
+ assert_difference('GsParameter.count', -1) do
+ delete :destroy, id: @gs_parameter.to_param
+ end
+
+ assert_redirected_to gs_parameters_path
+ end
+end
diff --git a/test/functional/manufacturers_controller_test.rb b/test/functional/manufacturers_controller_test.rb
index dad38e5..0b10f6d 100644
--- a/test/functional/manufacturers_controller_test.rb
+++ b/test/functional/manufacturers_controller_test.rb
@@ -2,14 +2,14 @@ require 'test_helper'
class ManufacturersControllerTest < ActionController::TestCase
setup do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @user.id)
@user.update_attributes!(:current_tenant_id => @tenant.id)
- @manufacturer = Factory.create(:manufacturer)
+ @manufacturer = FactoryGirl.create(:manufacturer)
@expected_status_if_not_authorized = :redirect
end
@@ -46,7 +46,7 @@ class ManufacturersControllerTest < ActionController::TestCase
#
# test "should create manufacturer" do
# assert_difference('Manufacturer.count') do
- # post :create, manufacturer: Factory.build(:manufacturer).attributes
+ # post :create, manufacturer: FactoryGirl.build(:manufacturer).attributes
# end
#
# assert_redirected_to manufacturer_path(assigns(:manufacturer))
diff --git a/test/functional/page_controller_test.rb b/test/functional/page_controller_test.rb
index a5ae5ad..2bc1b80 100644
--- a/test/functional/page_controller_test.rb
+++ b/test/functional/page_controller_test.rb
@@ -11,8 +11,8 @@ class PageControllerTest < ActionController::TestCase
test "a logged in user should get index" do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.users << @user
@@ -22,8 +22,8 @@ class PageControllerTest < ActionController::TestCase
end
test "a logged out user should be redirected to the login" do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.users << @user
diff --git a/test/functional/phone_book_entries_controller_test.rb b/test/functional/phone_book_entries_controller_test.rb
index 81c5b61..b340f0f 100644
--- a/test/functional/phone_book_entries_controller_test.rb
+++ b/test/functional/phone_book_entries_controller_test.rb
@@ -3,9 +3,9 @@ require 'test_helper'
class PhoneBookEntriesControllerTest < ActionController::TestCase
setup do
- @user1 = Factory.create(:user)
+ @user1 = FactoryGirl.create(:user)
pb = @user1.phone_books.first
- @user1_phone_book_entry = Factory.create(
+ @user1_phone_book_entry = FactoryGirl.create(
:phone_book_entry,
:phone_book_id => pb.id
)
diff --git a/test/functional/phone_books_controller_test.rb b/test/functional/phone_books_controller_test.rb
index a00f597..aef2890 100644
--- a/test/functional/phone_books_controller_test.rb
+++ b/test/functional/phone_books_controller_test.rb
@@ -2,19 +2,19 @@ require 'test_helper'
class PhoneBooksControllerTest < ActionController::TestCase
setup do
- @tenant = Factory.create(:tenant)
+ @tenant = FactoryGirl.create(:tenant)
@admins = @tenant.user_groups.find_or_create_by_name('Admins')
@users = @tenant.user_groups.find_or_create_by_name('Users')
- @user = Factory.create(:user)
+ @user = FactoryGirl.create(:user)
@tenant.users << @user
@users.users << @user
- @personal_phone_book = Factory.create(:phone_book,
+ @personal_phone_book = FactoryGirl.create(:phone_book,
:phone_bookable_type => @user.class.to_s,
:phone_bookable_id => @user.id
)
- phone_book_entry = Factory.create(:phone_book_entry)
+ phone_book_entry = FactoryGirl.create(:phone_book_entry)
@personal_phone_book.phone_book_entries << phone_book_entry
@expected_status_if_not_authorized = :redirect
@@ -34,7 +34,7 @@ class PhoneBooksControllerTest < ActionController::TestCase
end
test "should create phone_book" do
- phone_book2 = Factory.build(:phone_book,
+ phone_book2 = FactoryGirl.build(:phone_book,
:phone_bookable_type => @user.class.to_s,
:phone_bookable_id => @user.id
)
diff --git a/test/functional/phone_models_controller_test.rb b/test/functional/phone_models_controller_test.rb
index 2d1a87a..199be45 100644
--- a/test/functional/phone_models_controller_test.rb
+++ b/test/functional/phone_models_controller_test.rb
@@ -4,21 +4,21 @@ class PhoneModelsControllerTest < ActionController::TestCase
setup do
# Create a tenant:
- @tenant = Factory.create(:tenant)
+ @tenant = FactoryGirl.create(:tenant)
# Create a User who is member of the Tenant but has no special rights:
- @user = Factory.create(:user)
+ @user = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @user.id)
@user.update_attributes!(:current_tenant_id => @tenant.id)
# Create a User who is member of the Tenant and has super admin rights:
- @super_admin = Factory.create(:user)
+ @super_admin = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @super_admin.id)
@super_admin.update_attributes!(:current_tenant_id => @tenant.id)
# Create a PhoneModel
#
- @phone_model = Factory.create(:phone_model)
+ @phone_model = FactoryGirl.create(:phone_model)
end
[ '@user.id', '' ].each do |user_id_code|
@@ -44,7 +44,7 @@ class PhoneModelsControllerTest < ActionController::TestCase
session[:user_id] = eval( user_id_code )
assert_no_difference('PhoneModel.count') do
- post :create, manufacturer_id: @phone_model.manufacturer_id, phone_model: Factory.build(:phone_model,
+ post :create, manufacturer_id: @phone_model.manufacturer_id, phone_model: FactoryGirl.build(:phone_model,
:manufacturer_id => @phone_model.manufacturer_id).attributes
end
end
@@ -106,7 +106,7 @@ class PhoneModelsControllerTest < ActionController::TestCase
# # add routes first.
# test "should create phone_model as super admin" do
# assert_difference('PhoneModel.count') do
- # post :create, phone_model: Factory.build(:phone_model,
+ # post :create, phone_model: FactoryGirl.build(:phone_model,
# :manufacturer_id => @phone_model.manufacturer_id).attributes
# end
#
diff --git a/test/functional/phone_number_ranges_controller_test.rb b/test/functional/phone_number_ranges_controller_test.rb
index 39f28c4..9569f3e 100644
--- a/test/functional/phone_number_ranges_controller_test.rb
+++ b/test/functional/phone_number_ranges_controller_test.rb
@@ -5,7 +5,7 @@ class PhoneNumberRangesControllerTest < ActionController::TestCase
#TODO Uncomment tests once the views are implemented.
setup do
- @phone_number_range = Factory.create(:phone_number_range)
+ @phone_number_range = FactoryGirl.create(:phone_number_range)
end
test "should get index" do
diff --git a/test/functional/phone_numbers_controller_test.rb b/test/functional/phone_numbers_controller_test.rb
index ab0a4b2..b11e3e8 100644
--- a/test/functional/phone_numbers_controller_test.rb
+++ b/test/functional/phone_numbers_controller_test.rb
@@ -3,8 +3,8 @@ require 'test_helper'
class PhoneNumbersControllerTest < ActionController::TestCase
setup do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @user.id)
@@ -12,11 +12,11 @@ class PhoneNumbersControllerTest < ActionController::TestCase
@private_phone_book = @user.phone_books.first
- @private_phone_book_entry = Factory.create(
+ @private_phone_book_entry = FactoryGirl.create(
:phone_book_entry,
:phone_book => @private_phone_book
)
- @phone_number = Factory.create(
+ @phone_number = FactoryGirl.create(
:phone_number,
:phone_numberable => @private_phone_book_entry
)
diff --git a/test/functional/phones_controller_test.rb b/test/functional/phones_controller_test.rb
index 1b0aa55..f2cc716 100644
--- a/test/functional/phones_controller_test.rb
+++ b/test/functional/phones_controller_test.rb
@@ -6,7 +6,7 @@ class PhonesControllerTest < ActionController::TestCase
#TODO Uncomment tests once the route has been implemented.
# setup do
-# @phone = Factory.create(:phone)
+# @phone = FactoryGirl.create(:phone)
# end
#
# test "should get index" do
@@ -24,7 +24,7 @@ class PhonesControllerTest < ActionController::TestCase
# #
# # test "should create phone" do
# # assert_difference('Phone.count') do
-# # post :create, phone: Factory.build(:phone, :phone_model_id => @phone.phone_model_id).attributes
+# # post :create, phone: FactoryGirl.build(:phone, :phone_model_id => @phone.phone_model_id).attributes
# # end
# #
# # assert_redirected_to phone_path(assigns(:phone))
diff --git a/test/functional/phones_sip_accounts_controller_test.rb b/test/functional/phones_sip_accounts_controller_test.rb
index 967b8fe..834e502 100644
--- a/test/functional/phones_sip_accounts_controller_test.rb
+++ b/test/functional/phones_sip_accounts_controller_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class PhonesSipAccountsControllerTest < ActionController::TestCase
setup do
- @phones_sip_account = Factory.create(:phones_sip_account)
+ @phones_sip_account = FactoryGirl.create(:phones_sip_account)
end
# test "should get index" do
diff --git a/test/functional/route_elements_controller_test.rb b/test/functional/route_elements_controller_test.rb
new file mode 100644
index 0000000..3d7afaa
--- /dev/null
+++ b/test/functional/route_elements_controller_test.rb
@@ -0,0 +1,49 @@
+require 'test_helper'
+
+class RouteElementsControllerTest < ActionController::TestCase
+ setup do
+ @route_element = route_elements(:one)
+ end
+
+ test "should get index" do
+ get :index
+ assert_response :success
+ assert_not_nil assigns(:route_elements)
+ end
+
+ test "should get new" do
+ get :new
+ assert_response :success
+ end
+
+ test "should create route_element" do
+ assert_difference('RouteElement.count') do
+ post :create, route_element: @route_element.attributes
+ end
+
+ assert_redirected_to route_element_path(assigns(:route_element))
+ end
+
+ test "should show route_element" do
+ get :show, id: @route_element.to_param
+ assert_response :success
+ end
+
+ test "should get edit" do
+ get :edit, id: @route_element.to_param
+ assert_response :success
+ end
+
+ test "should update route_element" do
+ put :update, id: @route_element.to_param, route_element: @route_element.attributes
+ assert_redirected_to route_element_path(assigns(:route_element))
+ end
+
+ test "should destroy route_element" do
+ assert_difference('RouteElement.count', -1) do
+ delete :destroy, id: @route_element.to_param
+ end
+
+ assert_redirected_to route_elements_path
+ end
+end
diff --git a/test/functional/sip_accounts_controller_test.rb b/test/functional/sip_accounts_controller_test.rb
index 5c97dd2..e079718 100644
--- a/test/functional/sip_accounts_controller_test.rb
+++ b/test/functional/sip_accounts_controller_test.rb
@@ -3,10 +3,10 @@ require 'test_helper'
class SipAccountsControllerTest < ActionController::TestCase
setup do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @user.id)
- @sip_account = @user.sip_accounts.create( Factory.build(:sip_account).attributes )
+ @sip_account = @user.sip_accounts.create( FactoryGirl.build(:sip_account).attributes )
@parent_param = @sip_account.sip_accountable_type.foreign_key.to_sym
@parent_id = @sip_account.sip_accountable.id
@@ -32,7 +32,7 @@ class SipAccountsControllerTest < ActionController::TestCase
assert_difference('SipAccount.count') do
post :create,
@parent_param => @parent_id,
- sip_account: Factory.attributes_for(:sip_account)
+ sip_account: FactoryGirl.attributes_for(:sip_account)
end
end
diff --git a/test/functional/sip_domains_controller_test.rb b/test/functional/sip_domains_controller_test.rb
index f26ea02..5cbd519 100644
--- a/test/functional/sip_domains_controller_test.rb
+++ b/test/functional/sip_domains_controller_test.rb
@@ -2,7 +2,7 @@ require 'test_helper'
class SipDomainsControllerTest < ActionController::TestCase
setup do
- @sip_domain = Factory.create(:sip_domain)
+ @sip_domain = FactoryGirl.create(:sip_domain)
end
test "should get index" do
@@ -18,7 +18,7 @@ class SipDomainsControllerTest < ActionController::TestCase
test "should create sip_domain" do
assert_difference('SipDomain.count') do
- post :create, sip_domain: Factory.build(:sip_domain).attributes
+ post :create, sip_domain: FactoryGirl.build(:sip_domain).attributes
end
assert_redirected_to sip_domain_path(assigns(:sip_domain))
diff --git a/test/functional/tenants_controller_test.rb b/test/functional/tenants_controller_test.rb
index b4e2df4..7c5ec93 100644
--- a/test/functional/tenants_controller_test.rb
+++ b/test/functional/tenants_controller_test.rb
@@ -4,7 +4,7 @@ class TenantsControllerTest < ActionController::TestCase
# TODO Create tests which test that a login user has specific rights.
# setup do
- # @tenant = Factory.create(:tenant)
+ # @tenant = FactoryGirl.create(:tenant)
# end
#
# test "should get index" do
@@ -20,7 +20,7 @@ class TenantsControllerTest < ActionController::TestCase
#
# test "should create tenant" do
# assert_difference('Tenant.count') do
- # post :create, tenant: Factory.build(:tenant).attributes
+ # post :create, tenant: FactoryGirl.build(:tenant).attributes
# end
#
# assert_redirected_to tenant_path(assigns(:tenant))
diff --git a/test/functional/trigger_controller_test.rb b/test/functional/trigger_controller_test.rb
new file mode 100644
index 0000000..de64e4f
--- /dev/null
+++ b/test/functional/trigger_controller_test.rb
@@ -0,0 +1,14 @@
+require 'test_helper'
+
+class TriggerControllerTest < ActionController::TestCase
+ test "should get voicemail" do
+ get :voicemail
+ assert_response :success
+ end
+
+ test "should get fax" do
+ get :fax
+ assert_response :success
+ end
+
+end
diff --git a/test/functional/user_groups_controller_test.rb b/test/functional/user_groups_controller_test.rb
index 0e39048..6f0c753 100644
--- a/test/functional/user_groups_controller_test.rb
+++ b/test/functional/user_groups_controller_test.rb
@@ -4,7 +4,7 @@ class UserGroupsControllerTest < ActionController::TestCase
# TODO Create tests which test that a login user has specific rights.
# setup do
- # @user_group = Factory.create(:user_group)
+ # @user_group = FactoryGirl.create(:user_group)
# end
#
# test "should get index" do
@@ -20,7 +20,7 @@ class UserGroupsControllerTest < ActionController::TestCase
#
# test "should create user_group" do
# assert_difference('UserGroup.count') do
- # post :create, user_group: Factory.build(:user_group).attributes
+ # post :create, user_group: FactoryGirl.build(:user_group).attributes
# end
#
# assert_redirected_to user_group_path(assigns(:user_group))
diff --git a/test/functional/users_controller_test.rb b/test/functional/users_controller_test.rb
index d1898f7..987b3df 100644
--- a/test/functional/users_controller_test.rb
+++ b/test/functional/users_controller_test.rb
@@ -2,8 +2,8 @@ require 'test_helper'
class UsersControllerTest < ActionController::TestCase
setup do
- @tenant = Factory.create(:tenant)
- @user = Factory.create(:user)
+ @tenant = FactoryGirl.create(:tenant)
+ @user = FactoryGirl.create(:user)
@tenant.tenant_memberships.create(:user_id => @user.id)
@@ -30,7 +30,7 @@ class UsersControllerTest < ActionController::TestCase
# test "should create user" do
# session[:user_id] = nil
# assert_difference('User.count') do
- # post :create, user: Factory.build(:user).attributes
+ # post :create, user: FactoryGirl.build(:user).attributes
# end
#
# # assert_redirected_to user_path(assigns(:user))
diff --git a/test/unit/area_code_test.rb b/test/unit/area_code_test.rb
index 10c7c08..d59b290 100644
--- a/test/unit/area_code_test.rb
+++ b/test/unit/area_code_test.rb
@@ -2,6 +2,6 @@ require 'test_helper'
class AreaCodeTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:area_code).valid?
+ assert FactoryGirl.build(:area_code).valid?
end
end
diff --git a/test/unit/call_forward_test.rb b/test/unit/call_forward_test.rb
index 95716c5..afde3c0 100644
--- a/test/unit/call_forward_test.rb
+++ b/test/unit/call_forward_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class CallForwardTest < ActiveSupport::TestCase
test "should have a valid factory" do
- assert Factory.build(:call_forward).valid?
+ assert FactoryGirl.build(:call_forward).valid?
end
end
diff --git a/test/unit/call_route_test.rb b/test/unit/call_route_test.rb
new file mode 100644
index 0000000..5eb2e50
--- /dev/null
+++ b/test/unit/call_route_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class CallRouteTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert CallRoute.new.valid?
+ end
+end
diff --git a/test/unit/callthrough_test.rb b/test/unit/callthrough_test.rb
index c1c6ab3..5764c0d 100644
--- a/test/unit/callthrough_test.rb
+++ b/test/unit/callthrough_test.rb
@@ -30,7 +30,7 @@ class CallthroughTest < ActiveSupport::TestCase
@gemeinschaft_setup.save
super_tenant = Tenant.create(
- :name => SUPER_TENANT_NAME,
+ :name => GsParameter.get('SUPER_TENANT_NAME'),
:country_id => @gemeinschaft_setup.country.id,
:language_id => @gemeinschaft_setup.language_id,
:description => I18n.t('gemeinschaft_setups.initial_setup.super_tenant_description'),
@@ -94,14 +94,14 @@ class CallthroughTest < ActiveSupport::TestCase
# Check the amount of phone_numbers
#
- assert_equal 11, @tenant.phone_number_ranges.find_by_name(INTERNAL_EXTENSIONS).phone_numbers.count
- assert_equal 12, @tenant.phone_number_ranges.find_by_name(DIRECT_INWARD_DIALING_NUMBERS).phone_numbers.count
+ assert_equal 11, @tenant.phone_number_ranges.find_by_name(GsParameter.get('INTERNAL_EXTENSIONS')).phone_numbers.count
+ assert_equal 12, @tenant.phone_number_ranges.find_by_name(GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')).phone_numbers.count
end
test 'that a callthrough can only be created with at least one DID' do
assert_equal 0, Callthrough.count
- did = @tenant.phone_number_ranges.find_by_name(DIRECT_INWARD_DIALING_NUMBERS).phone_numbers.first
+ did = @tenant.phone_number_ranges.find_by_name(GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')).phone_numbers.first
callthrough = @tenant.callthroughs.build
@@ -118,7 +118,7 @@ class CallthroughTest < ActiveSupport::TestCase
# test 'that one DID can not be used by two different callthroughs' do
# assert_equal 0, Callthrough.count
- # did = @tenant.phone_number_ranges.find_by_name(DIRECT_INWARD_DIALING_NUMBERS).phone_numbers.first
+ # did = @tenant.phone_number_ranges.find_by_name(GsParameter.get('DIRECT_INWARD_DIALING_NUMBERS')).phone_numbers.first
# callthroughs = Array.new
# (1..2).each do |i|
diff --git a/test/unit/conference_invitee_test.rb b/test/unit/conference_invitee_test.rb
index bcc4c9b..2823709 100644
--- a/test/unit/conference_invitee_test.rb
+++ b/test/unit/conference_invitee_test.rb
@@ -3,11 +3,11 @@ require 'test_helper'
class ConferenceInviteeTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:conference_invitee).valid?
+ assert FactoryGirl.build(:conference_invitee).valid?
end
test "parent conference should not have a phone number twice" do
- invitee = Factory.create(:conference_invitee)
+ invitee = FactoryGirl.create(:conference_invitee)
conference = invitee.conference
phone_number = PhoneNumber.new(:number => invitee.phone_number.number)
invitee_bad = conference.conference_invitees.build(:phone_number => phone_number)
diff --git a/test/unit/conference_test.rb b/test/unit/conference_test.rb
index b7cce28..e7c05c9 100644
--- a/test/unit/conference_test.rb
+++ b/test/unit/conference_test.rb
@@ -3,42 +3,42 @@ require 'test_helper'
class ConferenceTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:conference).valid?
+ assert FactoryGirl.build(:conference).valid?
end
def test_dates_must_make_sense
# We can't create a conference in the past.
- assert !Factory.build(:conference, :start => Time.now - 1.day, :end => Time.now + 1.day).valid?
+ assert !FactoryGirl.build(:conference, :start => Time.now - 1.day, :end => Time.now + 1.day).valid?
# But we can create a conference which started 2 minutes ago.
- assert Factory.build(:conference, :start => Time.now - 2.minutes, :end => Time.now + 1.hour).valid?
+ assert FactoryGirl.build(:conference, :start => Time.now - 2.minutes, :end => Time.now + 1.hour).valid?
# The end must be before the start.
- assert !Factory.build(:conference, :start => Time.now + 2.day, :end => Time.now + 1.day).valid?
+ assert !FactoryGirl.build(:conference, :start => Time.now + 2.day, :end => Time.now + 1.day).valid?
# No date at all is fine.
- assert Factory.build(:conference, :start => nil, :end => nil).valid?
+ assert FactoryGirl.build(:conference, :start => nil, :end => nil).valid?
# Just start or just end is not ok.
- assert !Factory.build(:conference, :start => nil, :end => Time.now + 1.day).valid?
- assert !Factory.build(:conference, :start => Time.now + 1.day, :end => nil).valid?
+ assert !FactoryGirl.build(:conference, :start => nil, :end => Time.now + 1.day).valid?
+ assert !FactoryGirl.build(:conference, :start => Time.now + 1.day, :end => nil).valid?
end
def test_pin_must_be_nil_or_more_than_6_digits
- conference = Factory.build(:conference, :pin => nil)
+ conference = FactoryGirl.build(:conference, :pin => nil)
assert conference.valid?
- (MINIMUM_PIN_LENGTH - 1).times do |i|
+ (GsParameter.get('MINIMUM_PIN_LENGTH') - 1).times do |i|
pin = "#{10**i}"
conference.pin = pin
assert !conference.valid?
end
- conference.pin = "#{10**(MINIMUM_PIN_LENGTH - 1)}"
+ conference.pin = "#{10**(GsParameter.get('MINIMUM_PIN_LENGTH') - 1)}"
assert conference.valid?
- conference.pin = "-#{10**(MINIMUM_PIN_LENGTH - 1)}"
+ conference.pin = "-#{10**(GsParameter.get('MINIMUM_PIN_LENGTH') - 1)}"
assert !conference.valid?
conference.pin = 'Teststring'
diff --git a/test/unit/country_test.rb b/test/unit/country_test.rb
index 4933843..06f520e 100644
--- a/test/unit/country_test.rb
+++ b/test/unit/country_test.rb
@@ -2,6 +2,6 @@ require 'test_helper'
class CountryTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:country).valid?
+ assert FactoryGirl.build(:country).valid?
end
end
diff --git a/test/unit/gateway_parameter_test.rb b/test/unit/gateway_parameter_test.rb
new file mode 100644
index 0000000..cec1e1a
--- /dev/null
+++ b/test/unit/gateway_parameter_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class GatewayParameterTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert GatewayParameter.new.valid?
+ end
+end
diff --git a/test/unit/gateway_setting_test.rb b/test/unit/gateway_setting_test.rb
new file mode 100644
index 0000000..86176b4
--- /dev/null
+++ b/test/unit/gateway_setting_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class GatewaySettingTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert GatewaySetting.new.valid?
+ end
+end
diff --git a/test/unit/gateway_test.rb b/test/unit/gateway_test.rb
new file mode 100644
index 0000000..4c40dc9
--- /dev/null
+++ b/test/unit/gateway_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class GatewayTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert Gateway.new.valid?
+ end
+end
diff --git a/test/unit/gemeinschaft_setup_test.rb b/test/unit/gemeinschaft_setup_test.rb
index 5ea6523..bd398ff 100644
--- a/test/unit/gemeinschaft_setup_test.rb
+++ b/test/unit/gemeinschaft_setup_test.rb
@@ -2,6 +2,6 @@ require 'test_helper'
class GemeinschaftSetupTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:gemeinschaft_setup).valid?
+ assert FactoryGirl.build(:gemeinschaft_setup).valid?
end
end
diff --git a/test/unit/gs_parameter_test.rb b/test/unit/gs_parameter_test.rb
new file mode 100644
index 0000000..2e3793a
--- /dev/null
+++ b/test/unit/gs_parameter_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class GsParameterTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert GsParameter.new.valid?
+ end
+end
diff --git a/test/unit/helpers/trigger_helper_test.rb b/test/unit/helpers/trigger_helper_test.rb
new file mode 100644
index 0000000..5f81a88
--- /dev/null
+++ b/test/unit/helpers/trigger_helper_test.rb
@@ -0,0 +1,4 @@
+require 'test_helper'
+
+class TriggerHelperTest < ActionView::TestCase
+end
diff --git a/test/unit/language_test.rb b/test/unit/language_test.rb
index 3308735..4a8cd77 100644
--- a/test/unit/language_test.rb
+++ b/test/unit/language_test.rb
@@ -2,6 +2,6 @@ require 'test_helper'
class LanguageTest < ActiveSupport::TestCase
test "has a valid factory" do
- assert Factory.build(:language).valid?
+ assert FactoryGirl.build(:language).valid?
end
end
diff --git a/test/unit/manufacturer_test.rb b/test/unit/manufacturer_test.rb
index 635a977..012d34d 100644
--- a/test/unit/manufacturer_test.rb
+++ b/test/unit/manufacturer_test.rb
@@ -2,18 +2,18 @@ require 'test_helper'
class ManufacturerTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:manufacturer).valid?
+ assert FactoryGirl.build(:manufacturer).valid?
end
# StateMachine Tests:
def test_that_the_initial_state_should_be_active
- @manufacturer = Factory.create(:manufacturer)
+ @manufacturer = FactoryGirl.create(:manufacturer)
assert_equal 'active', @manufacturer.state
assert @manufacturer.active?
end
def test_not_active_state_will_not_be_displayed
- @manufacturer = Factory.create(:manufacturer)
+ @manufacturer = FactoryGirl.create(:manufacturer)
assert_equal 1, Manufacturer.count
@manufacturer.deactivate!
diff --git a/test/unit/oui_test.rb b/test/unit/oui_test.rb
index de48a97..cff5864 100644
--- a/test/unit/oui_test.rb
+++ b/test/unit/oui_test.rb
@@ -2,11 +2,11 @@ require 'test_helper'
class OuiTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:oui).valid?
+ assert FactoryGirl.build(:oui).valid?
end
def test_that_the_initial_state_should_be_active
- @oui = Factory.create(:oui)
+ @oui = FactoryGirl.create(:oui)
assert_equal 'active', @oui.state
assert @oui.active?
end
diff --git a/test/unit/phone_book_entry_test.rb b/test/unit/phone_book_entry_test.rb
index c8d639b..2613398 100644
--- a/test/unit/phone_book_entry_test.rb
+++ b/test/unit/phone_book_entry_test.rb
@@ -2,17 +2,17 @@ require 'test_helper'
class PhoneBookEntryTest < ActiveSupport::TestCase
def test_should_be_valid
- assert Factory.build(:phone_book_entry).valid?
+ assert FactoryGirl.build(:phone_book_entry).valid?
end
# TODO Fix this test.
# test "only user can read entries in private phone books" do
- # user = Factory.create(:user)
- # phone_book = Factory.create(:phone_book, :phone_bookable_type => 'User', :phone_bookable_id => user.id)
- # phone_book_entry = Factory.create(:phone_book_entry, :phone_book_id => phone_book.id)
+ # user = FactoryGirl.create(:user)
+ # phone_book = FactoryGirl.create(:phone_book, :phone_bookable_type => 'User', :phone_bookable_id => user.id)
+ # phone_book_entry = FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book.id)
- # evil_user = Factory.create(:user)
+ # evil_user = FactoryGirl.create(:user)
# user_ability = Ability.new( user )
# evil_user_ability = Ability.new( evil_user )
@@ -24,17 +24,17 @@ class PhoneBookEntryTest < ActiveSupport::TestCase
# end
def test_that_the_initial_state_should_be_active
- @phone_book_entry = Factory.create(:phone_book_entry)
+ @phone_book_entry = FactoryGirl.create(:phone_book_entry)
assert_equal 'active', @phone_book_entry.state
assert @phone_book_entry.active?
end
test "a destroyed phone_book will destroy all phone_book_entries" do
- phone_book = Factory.create(:phone_book)
- 10.times { Factory.create(:phone_book_entry, :phone_book_id => phone_book.id) }
+ phone_book = FactoryGirl.create(:phone_book)
+ 10.times { FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book.id) }
- phone_book2 = Factory.create(:phone_book)
- 5.times { Factory.create(:phone_book_entry, :phone_book_id => phone_book2.id) }
+ phone_book2 = FactoryGirl.create(:phone_book)
+ 5.times { FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book2.id) }
assert_equal 15, PhoneBookEntry.all.count
@@ -44,7 +44,7 @@ class PhoneBookEntryTest < ActiveSupport::TestCase
end
test "that the value_of_to_s field is filled" do
- phone_book_entry = Factory.create(:phone_book_entry)
+ phone_book_entry = FactoryGirl.create(:phone_book_entry)
assert_equal phone_book_entry.value_of_to_s, phone_book_entry.to_s
end
diff --git a/test/unit/phone_book_test.rb b/test/unit/phone_book_test.rb
index 7db48f8..b820521 100644
--- a/test/unit/phone_book_test.rb
+++ b/test/unit/phone_book_test.rb
@@ -2,15 +2,15 @@ require 'test_helper'
class PhoneBookTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:phone_book).valid?
+ assert FactoryGirl.build(:phone_book).valid?
end
def test_should_have_unique_name_depending_on_type
- user1 = Factory.create(:user)
- user2 = Factory.create(:user)
- tenant = Factory.create(:tenant)
+ user1 = FactoryGirl.create(:user)
+ user2 = FactoryGirl.create(:user)
+ tenant = FactoryGirl.create(:tenant)
- phonebook = Factory.create(:phone_book, :phone_bookable => user1)
+ phonebook = FactoryGirl.create(:phone_book, :phone_bookable => user1)
assert !user1.phone_books.build(:name => phonebook.name).valid?
assert user2.phone_books.build(:name => phonebook.name).valid?
assert tenant.phone_books.build(:name => phonebook.name).valid?
@@ -20,7 +20,7 @@ class PhoneBookTest < ActiveSupport::TestCase
# test "User gets a private phone book with rw rights" do
- # user = Factory.create(:user)
+ # user = FactoryGirl.create(:user)
# assert_equal 1, user.phone_books.count
# phone_book = user.phone_books.first
@@ -34,9 +34,9 @@ class PhoneBookTest < ActiveSupport::TestCase
# # Lets test some stuff about the phone_book_entries
# assert_equal 0, phone_book.phone_book_entries.count
- # entry1 = Factory.create(:phone_book_entry, :phone_book_id => phone_book.id)
- # entry2 = Factory.create(:phone_book_entry, :phone_book_id => phone_book.id)
- # entry3 = Factory.create(:phone_book_entry, :phone_book_id => phone_book.id)
+ # entry1 = FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book.id)
+ # entry2 = FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book.id)
+ # entry3 = FactoryGirl.create(:phone_book_entry, :phone_book_id => phone_book.id)
# assert_equal 3, phone_book.phone_book_entries.count
# assert_equal 1, PhoneBookEntry.where(:id => entry1.id).count
@@ -50,22 +50,22 @@ class PhoneBookTest < ActiveSupport::TestCase
# end
test "Tenant gets automatically one phone book and can destroy it" do
- tenant = Factory.create(:tenant)
+ tenant = FactoryGirl.create(:tenant)
assert_equal 1, tenant.phone_books.count
tenant.phone_books.first.destroy
assert_equal 0, tenant.phone_books.count
end
# test "only tenant members can read a tenant phone book" do
- # tenant = Factory.create(:tenant)
- # user = Factory.create(:user)
+ # tenant = FactoryGirl.create(:tenant)
+ # user = FactoryGirl.create(:user)
# tenant.users << user
# tenant.save
# user.current_tenant = tenant
# user.save
- # phone_book = Factory.create(:phone_book, :phone_bookable_type => 'Tenant', :phone_bookable_id => tenant.id)
+ # phone_book = FactoryGirl.create(:phone_book, :phone_bookable_type => 'Tenant', :phone_bookable_id => tenant.id)
- # evil_user = Factory.create(:user)
+ # evil_user = FactoryGirl.create(:user)
# user_ability = Ability.new( user )
# evil_user_ability = Ability.new( evil_user )
@@ -79,12 +79,12 @@ class PhoneBookTest < ActiveSupport::TestCase
# test "tenant's phone book can not be edited by tenant members" do
- # tenant = Factory.create(:tenant)
- # user = Factory.create(:user)
+ # tenant = FactoryGirl.create(:tenant)
+ # user = FactoryGirl.create(:user)
# tenant.users << user
- # phone_book = Factory.create(:phone_book, :phone_bookable_type => 'Tenant', :phone_bookable_id => tenant.id)
+ # phone_book = FactoryGirl.create(:phone_book, :phone_bookable_type => 'Tenant', :phone_bookable_id => tenant.id)
- # evil_user = Factory.create(:user)
+ # evil_user = FactoryGirl.create(:user)
# user_ability = Ability.new( user )
# evil_user_ability = Ability.new( evil_user )
@@ -96,10 +96,10 @@ class PhoneBookTest < ActiveSupport::TestCase
# end
# test "only user can manage his private phone book after creating it" do
- # user = Factory.create(:user)
- # phone_book = Factory.create(:phone_book, :phone_bookable_type => 'User', :phone_bookable_id => user.id)
+ # user = FactoryGirl.create(:user)
+ # phone_book = FactoryGirl.create(:phone_book, :phone_bookable_type => 'User', :phone_bookable_id => user.id)
- # evil_user = Factory.create(:user)
+ # evil_user = FactoryGirl.create(:user)
# user_ability = Ability.new( user )
# evil_user_ability = Ability.new( evil_user )
@@ -111,7 +111,7 @@ class PhoneBookTest < ActiveSupport::TestCase
# end
def test_that_the_initial_state_should_be_active
- @phone_book = Factory.create(:phone_book)
+ @phone_book = FactoryGirl.create(:phone_book)
assert_equal 'active', @phone_book.state
assert @phone_book.active?
end
diff --git a/test/unit/phone_model_test.rb b/test/unit/phone_model_test.rb
index e358cf9..ef293f4 100644
--- a/test/unit/phone_model_test.rb
+++ b/test/unit/phone_model_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class PhoneModelTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:phone_model).valid?
+ assert FactoryGirl.build(:phone_model).valid?
end
end
diff --git a/test/unit/phone_number_range_test.rb b/test/unit/phone_number_range_test.rb
index 1770299..e70cd60 100644
--- a/test/unit/phone_number_range_test.rb
+++ b/test/unit/phone_number_range_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class PhoneNumberRangeTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:phone_number_range).valid?
+ assert FactoryGirl.build(:phone_number_range).valid?
end
end
diff --git a/test/unit/phone_number_test.rb b/test/unit/phone_number_test.rb
index e10b20c..c991b0f 100644
--- a/test/unit/phone_number_test.rb
+++ b/test/unit/phone_number_test.rb
@@ -5,17 +5,17 @@ require 'test_helper'
class PhoneNumberTest < ActiveSupport::TestCase
test "should have valid factory" do
- assert Factory.build(:phone_number).valid?
+ assert FactoryGirl.build(:phone_number).valid?
end
def test_that_the_initial_state_should_be_active
- @phone_number = Factory.create(:phone_number)
+ @phone_number = FactoryGirl.create(:phone_number)
assert_equal 'active', @phone_number.state
assert @phone_number.active?
end
test "that the value_of_to_s field is filled" do
- phone_number = Factory.create(:phone_number)
+ phone_number = FactoryGirl.create(:phone_number)
assert_equal phone_number.value_of_to_s, phone_number.to_s
end
@@ -198,9 +198,9 @@ class PhoneNumberTest < ActiveSupport::TestCase
AreaCode.create(:country => germany, :name => "Hohenmocker", :area_code => "39993")
# create a tenant
- tenant = Factory.create(:tenant, :country_id => germany.id)
+ tenant = FactoryGirl.create(:tenant, :country_id => germany.id)
# create some extensions
- internal_extension_range = tenant.phone_number_ranges.create(:name => INTERNAL_EXTENSIONS)
+ internal_extension_range = tenant.phone_number_ranges.create(:name => GsParameter.get('INTERNAL_EXTENSIONS'))
['2000', '2001', '2003', '2004', '2005', '2006', '2007', '2008', '2009', '2010', '5', '99'].each do |extension|
internal_extension_range.phone_numbers.create(:name => "Extension #{extension}", :number => extension)
end
@@ -216,7 +216,7 @@ class PhoneNumberTest < ActiveSupport::TestCase
# Language.create(:name => 'Deutsch', :code => 'de')
# AreaCode.create(:country => germany, :name => "Bendorf", :area_code => "2622")
- # @sip_domain = Factory.create(:sip_domain)
+ # @sip_domain = FactoryGirl.create(:sip_domain)
# @tenant = @sip_domain.tenants.build(:name => 'AMOOMA GmbH')
# @tenant.country = Country.first
@@ -226,8 +226,8 @@ class PhoneNumberTest < ActiveSupport::TestCase
# @tenant.generate_internal_extensions
- # sip_account = @tenant.sip_accounts.build(Factory.create(:sip_account).attributes)
- # phone_number = sip_account.phone_numbers.create(Factory.build(:phone_number, :number => '10').attributes)
+ # sip_account = @tenant.sip_accounts.build(FactoryGirl.create(:sip_account).attributes)
+ # phone_number = sip_account.phone_numbers.create(FactoryGirl.build(:phone_number, :number => '10').attributes)
# phone_number_evil = sip_account.phone_numbers.build(phone_number.attributes)
# assert phone_number.valid?
@@ -235,14 +235,14 @@ class PhoneNumberTest < ActiveSupport::TestCase
# end
# test "has to be unique per SIP domain even for different tenants" do
- # provider_sip_domain = Factory.create(:sip_domain)
+ # provider_sip_domain = FactoryGirl.create(:sip_domain)
# tenants = []
# sip_accounts = []
# 2.times { |i|
- # tenants[i] = provider_sip_domain.tenants.create(Factory.build(:tenant, :internal_extension_ranges => '10-20').attributes)
+ # tenants[i] = provider_sip_domain.tenants.create(FactoryGirl.build(:tenant, :internal_extension_ranges => '10-20').attributes)
# tenants[i].generate_internal_extensions
- # sip_accounts[i] = tenants[i].sip_accounts.build(Factory.build(:sip_account, :tenant_id => tenants[i].id).attributes)
+ # sip_accounts[i] = tenants[i].sip_accounts.build(FactoryGirl.build(:sip_account, :tenant_id => tenants[i].id).attributes)
# sip_accounts[i].phone_numbers.build(:number => '10')
# }
# sip_accounts[0].save
diff --git a/test/unit/phone_test.rb b/test/unit/phone_test.rb
index 4ad21df..b9d33af 100644
--- a/test/unit/phone_test.rb
+++ b/test/unit/phone_test.rb
@@ -3,19 +3,19 @@ require 'test_helper'
class PhoneTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:phone).valid?
+ assert FactoryGirl.build(:phone).valid?
end
# test "should destroy_all phones_sip_accounts if the phoneable changed" do
- # sip_domain = Factory.create(:sip_domain)
- # tenant = sip_domain.tenants.create(Factory.build(:tenant).attributes)
+ # sip_domain = FactoryGirl.create(:sip_domain)
+ # tenant = sip_domain.tenants.create(FactoryGirl.build(:tenant).attributes)
#
- # user1 = Factory.create(:user)
- # user2 = Factory.create(:user)
+ # user1 = FactoryGirl.create(:user)
+ # user2 = FactoryGirl.create(:user)
# tenant.tenant_memberships.create(:user_id => user1.id)
# tenant.tenant_memberships.create(:user_id => user2.id)
#
- # phone = Factory.create(:phone, :phoneable => tenant)
+ # phone = FactoryGirl.create(:phone, :phoneable => tenant)
#
# # Nothing there
# #
@@ -28,7 +28,7 @@ class PhoneTest < ActiveSupport::TestCase
#
# # create some sip_accounts associated to phone
# #
- # 3.times { Factory.create(:sip_account, :sip_accountable => user1, :tenant_id => tenant.id) }
+ # 3.times { FactoryGirl.create(:sip_account, :sip_accountable => user1, :tenant_id => tenant.id) }
# SipAccount.all.each do |sip_account|
# phone.phones_sip_accounts.create(:sip_account_id => sip_account.id)
# end
diff --git a/test/unit/route_element_test.rb b/test/unit/route_element_test.rb
new file mode 100644
index 0000000..807a4ca
--- /dev/null
+++ b/test/unit/route_element_test.rb
@@ -0,0 +1,7 @@
+require 'test_helper'
+
+class RouteElementTest < ActiveSupport::TestCase
+ def test_should_be_valid
+ assert RouteElement.new.valid?
+ end
+end
diff --git a/test/unit/sip_account_test.rb b/test/unit/sip_account_test.rb
index 6595ccc..e85e493 100644
--- a/test/unit/sip_account_test.rb
+++ b/test/unit/sip_account_test.rb
@@ -3,21 +3,21 @@ require 'test_helper'
class SipAccountTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:sip_account).valid?
+ assert FactoryGirl.build(:sip_account).valid?
end
test "that the value_of_to_s field is filled" do
- sip_account = Factory.create(:sip_account)
+ sip_account = FactoryGirl.create(:sip_account)
assert_equal sip_account.value_of_to_s, sip_account.to_s
end
test "should have a unique auth_name per sip_domain" do
- provider_sip_domain = Factory.create(:sip_domain)
+ provider_sip_domain = FactoryGirl.create(:sip_domain)
tenants = []
sip_accounts = []
2.times { |i|
- tenants[i] = provider_sip_domain.tenants.create(Factory.build(:tenant).attributes)
- sip_accounts[i] = Factory.build(
+ tenants[i] = provider_sip_domain.tenants.create(FactoryGirl.build(:tenant).attributes)
+ sip_accounts[i] = FactoryGirl.build(
:sip_account,
:sip_accountable => tenants[i],
:auth_name => "somerandomauthname",
diff --git a/test/unit/sip_domain_test.rb b/test/unit/sip_domain_test.rb
index 5d31f69..61ac89a 100644
--- a/test/unit/sip_domain_test.rb
+++ b/test/unit/sip_domain_test.rb
@@ -3,7 +3,7 @@ require 'test_helper'
class SipDomainTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:sip_domain).valid?
+ assert FactoryGirl.build(:sip_domain).valid?
end
end
diff --git a/test/unit/tenant_membership_test.rb b/test/unit/tenant_membership_test.rb
index 8e7a191..ba57eae 100644
--- a/test/unit/tenant_membership_test.rb
+++ b/test/unit/tenant_membership_test.rb
@@ -2,11 +2,11 @@ require 'test_helper'
class TenantMembershipTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:tenant_membership).valid?
+ assert FactoryGirl.build(:tenant_membership).valid?
end
def test_that_the_initial_state_should_be_active
- @tenant_membership = Factory.create(:tenant_membership)
+ @tenant_membership = FactoryGirl.create(:tenant_membership)
assert_equal 'active', @tenant_membership.state
assert @tenant_membership.active?
end
diff --git a/test/unit/tenant_test.rb b/test/unit/tenant_test.rb
index 4d4abce..0b342ba 100644
--- a/test/unit/tenant_test.rb
+++ b/test/unit/tenant_test.rb
@@ -2,23 +2,23 @@ require 'test_helper'
class TenantTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:tenant).valid?
+ assert FactoryGirl.build(:tenant).valid?
end
def test_should_have_unique_name
- tenant = Factory.create(:tenant)
- assert !Factory.build(:tenant, :name => tenant.name).valid?
- assert Factory.build(:tenant, :name => "different_#{tenant.name}").valid?
+ tenant = FactoryGirl.create(:tenant)
+ assert !FactoryGirl.build(:tenant, :name => tenant.name).valid?
+ assert FactoryGirl.build(:tenant, :name => "different_#{tenant.name}").valid?
end
def test_that_the_initial_state_should_be_active
- @tenant = Factory.create(:tenant)
+ @tenant = FactoryGirl.create(:tenant)
assert_equal 'active', @tenant.state
assert @tenant.active?
end
def test_not_active_state_will_not_be_displayed
- @tenant = Factory.create(:tenant)
+ @tenant = FactoryGirl.create(:tenant)
assert_equal 1, Tenant.count
@tenant.deactivate!
diff --git a/test/unit/user_group_membership_test.rb b/test/unit/user_group_membership_test.rb
index 251229f..34a577c 100644
--- a/test/unit/user_group_membership_test.rb
+++ b/test/unit/user_group_membership_test.rb
@@ -2,29 +2,29 @@ require 'test_helper'
class UserGroupMembershipTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:user_group_membership).valid?
+ assert FactoryGirl.build(:user_group_membership).valid?
end
def test_should_have_unique_members_in_each_group
- group1 = Factory.create(:user_group)
- group2 = Factory.create(:user_group)
- user1 = Factory.create(:user)
- user2 = Factory.create(:user)
- member = Factory.create(
+ group1 = FactoryGirl.create(:user_group)
+ group2 = FactoryGirl.create(:user_group)
+ user1 = FactoryGirl.create(:user)
+ user2 = FactoryGirl.create(:user)
+ member = FactoryGirl.create(
:user_group_membership,
:user_id => user1.id,
:user_group_id => group1.id
)
- assert !Factory.build(
+ assert !FactoryGirl.build(
:user_group_membership,
:user_id => user1.id,
:user_group_id => group1.id
).valid?
- assert Factory.build(
+ assert FactoryGirl.build(
:user_group_membership,
:user_id => user1.id,
:user_group_id => group2.id
).valid?
- assert Factory.build(
+ assert FactoryGirl.build(
:user_group_membership,
:user_id => user2.id,
:user_group_id => group1.id
@@ -32,7 +32,7 @@ class UserGroupMembershipTest < ActiveSupport::TestCase
end
def test_that_the_initial_state_should_be_active
- @user_group_membership = Factory.create(:user_group_membership)
+ @user_group_membership = FactoryGirl.create(:user_group_membership)
assert_equal 'active', @user_group_membership.state
assert @user_group_membership.active?
end
diff --git a/test/unit/user_group_test.rb b/test/unit/user_group_test.rb
index 5e815a8..1023bd6 100644
--- a/test/unit/user_group_test.rb
+++ b/test/unit/user_group_test.rb
@@ -2,23 +2,23 @@ require 'test_helper'
class UserGroupTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:user_group).valid?
+ assert FactoryGirl.build(:user_group).valid?
end
def test_should_have_unique_name_on_same_tenant
- tenant1 = Factory.create(:tenant)
- tenant2 = Factory.create(:tenant)
- group = Factory.create(:user_group, :tenant_id => tenant1.id)
- assert !Factory.build(:user_group, :name => group.name, :tenant_id => tenant1.id).valid?
- assert Factory.build(:user_group, :name => group.name, :tenant_id => tenant2.id).valid?
- assert Factory.build(:user_group, :name => "different_#{group.name}", :tenant_id => tenant1.id).valid?
+ tenant1 = FactoryGirl.create(:tenant)
+ tenant2 = FactoryGirl.create(:tenant)
+ group = FactoryGirl.create(:user_group, :tenant_id => tenant1.id)
+ assert !FactoryGirl.build(:user_group, :name => group.name, :tenant_id => tenant1.id).valid?
+ assert FactoryGirl.build(:user_group, :name => group.name, :tenant_id => tenant2.id).valid?
+ assert FactoryGirl.build(:user_group, :name => "different_#{group.name}", :tenant_id => tenant1.id).valid?
end
test "user_group_membership only available for tenant_memberships" do
- good_tenant = Factory.create(:tenant)
- evil_tenant = Factory.create(:tenant)
+ good_tenant = FactoryGirl.create(:tenant)
+ evil_tenant = FactoryGirl.create(:tenant)
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
good_tenant.tenant_memberships.create(:user_id => user.id)
good_user_group = good_tenant.user_groups.create(:name => 'Example')
diff --git a/test/unit/user_test.rb b/test/unit/user_test.rb
index bb89e77..5fa1e4a 100644
--- a/test/unit/user_test.rb
+++ b/test/unit/user_test.rb
@@ -3,21 +3,21 @@ require 'test_helper'
class UserTest < ActiveSupport::TestCase
def test_should_have_a_valid_factory
- assert Factory.build(:user).valid?
+ assert FactoryGirl.build(:user).valid?
end
def test_should_have_a_unique_email_address
- user = Factory.create(:user)
- assert !Factory.build(:user, :email => user.email).valid?
- assert Factory.build(:user, :email => "different_#{user.email}").valid?
+ user = FactoryGirl.create(:user)
+ assert !FactoryGirl.build(:user, :email => user.email).valid?
+ assert FactoryGirl.build(:user, :email => "different_#{user.email}").valid?
end
def test_can_not_move_to_a_current_tenant_without_a_membership_relation
- super_tenant = Factory.create(:tenant)
- good_tenant = Factory.create(:tenant)
- evil_tenant = Factory.create(:tenant)
+ super_tenant = FactoryGirl.create(:tenant)
+ good_tenant = FactoryGirl.create(:tenant)
+ evil_tenant = FactoryGirl.create(:tenant)
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
super_tenant.tenant_memberships.create(:user_id => user.id)
good_tenant.tenant_memberships.create(:user_id => user.id)
@@ -27,7 +27,7 @@ class UserTest < ActiveSupport::TestCase
end
test "should be possible to modify the user without changing the PIN" do
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
pin_salt = user.pin_salt
pin_hash = user.pin_hash
user.middle_name = "#{user.middle_name} Foo"
@@ -39,7 +39,7 @@ class UserTest < ActiveSupport::TestCase
end
test "should be possible to change the PIN" do
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
pin_salt = user.pin_salt
pin_hash = user.pin_hash
new_pin = '453267'
@@ -52,7 +52,7 @@ class UserTest < ActiveSupport::TestCase
end
test "should not be possible to change the PIN if the confirmation does not match" do
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
pin_salt = user.pin_salt
pin_hash = user.pin_hash
user.new_pin = '123001'
@@ -67,7 +67,7 @@ class UserTest < ActiveSupport::TestCase
end
test "PIN must be numeric" do
- user = Factory.create(:user)
+ user = FactoryGirl.create(:user)
new_pin = 'xxxx'
user.new_pin = new_pin
user.new_pin_confirmation = new_pin