From 41aa3e0d4e664b3a6a6e6145364379515f60e3ec Mon Sep 17 00:00:00 2001 From: Josh Nussbaum Date: Tue, 30 Nov 2010 15:12:47 -0500 Subject: [PATCH] update to 0.30.1 --- LICENSE | 23 + README.markdown => README.md | 9 +- Rakefile | 150 +- app/controllers/faqs_controller.rb | 4 - .../admin/question_categories_helper.rb | 12 - app/helpers/faqs_helper.rb | 2 - .../admin/question_categories/edit.html.erb | 13 +- .../admin/question_categories/index.html.erb | 39 +- .../admin/question_categories/new.html.erb | 8 +- app/views/faqs/index.html.erb | 14 +- autotest/discover.rb | 2 + config/locales/en-GB.yml | 3 +- config/locales/en-US.yml | 1 + config/routes.rb | 8 +- db/sample/question_categories.yml | 8 - db/sample/questions.yml | 39 - faq_extension.rb | 20 - faq_hooks.rb | 5 - lib/generators/spree_faq/install_generator.rb | 17 + .../20090526213535_create_questions.rb | 0 ...090526213550_create_question_categories.rb | 0 .../javascripts/jquery.scrollTo-min.js | 0 .../public}/stylesheets/spree_faq.css | 0 lib/spree_faq.rb | 3 + lib/spree_faq/engine.rb | 12 + lib/spree_faq_hooks.rb | 6 + lib/tasks/faq_extension_tasks.rake | 30 - spec/controllers/faqs_controller_spec.rb | 9 - .../admin/question_categories_helper_spec.rb | 5 - spec/helpers/faqs_helper_spec.rb | 5 - spec/spec_helper.rb | 57 +- spec/test_app/Gemfile | 19 + spec/test_app/Gemfile.lock | 188 + spec/test_app/Rakefile | 7 + .../app/controllers/application_controller.rb | 3 + .../app/helpers/application_helper.rb | 2 + .../app/views/layouts/application.html.erb | 14 + spec/test_app/config.ru | 4 + spec/test_app/config/application.rb | 42 + spec/test_app/config/boot.rb | 13 + spec/test_app/config/database.yml | 17 + spec/test_app/config/environment.rb | 5 + spec/test_app/config/environments/cucumber.rb | 38 + .../config/environments/development.rb | 26 + .../config/environments/production.rb | 49 + spec/test_app/config/environments/test.rb | 62 + .../initializers/backtrace_silencers.rb | 7 + .../config/initializers/inflections.rb | 10 + .../config/initializers/mime_types.rb | 5 + .../config/initializers/secret_token.rb | 7 + .../config/initializers/session_store.rb | 8 + spec/test_app/config/locales/en.yml | 5 + spec/test_app/config/routes.rb | 58 + spec/test_app/db/cucumber.sqlite3 | Bin 0 -> 137216 bytes spec/test_app/db/default/countries.yml | 1583 +++++++ spec/test_app/db/default/roles.yml | 7 + spec/test_app/db/default/states.yml | 256 ++ spec/test_app/db/default/zone_members.yml | 169 + spec/test_app/db/default/zones.yml | 13 + .../20090526213535_create_questions.rb | 17 + ...090526213550_create_question_categories.rb | 14 + .../20090823005402_spree_zero_nine_zero.rb | 442 ++ ...2342_create_indexes_for_inventory_units.rb | 12 + ..._count_on_hand_to_variants_and_products.rb | 36 + ...91007134354_change_taxons_to_nested_set.rb | 40 + ...008091614_move_to_configurable_gateways.rb | 55 + ...0091012120519_product_groups_and_scopes.rb | 25 + ...10842_add_open_id_authentication_tables.rb | 20 + ...0091015153048_add_openid_field_to_users.rb | 19 + ...1016174634_change_preference_value_type.rb | 10 + ...91017175558_create_billing_integrations.rb | 16 + .../20091021133257_charge_refactoring.rb | 35 + .../20091104151730_add_some_indexes.rb | 21 + .../20091126190904_checkout_state_machine.rb | 13 + .../20091209153045_state_for_shipments.rb | 9 + ...209202200_make_state_events_polymorphic.rb | 12 + ...211203813_ship_address_id_for_checkouts.rb | 9 + ...161118_shipping_method_id_for_checkouts.rb | 9 + ...91213222815_creditcard_last_four_digits.rb | 19 + ...14183826_populate_legacy_shipment_state.rb | 19 + .../migrate/20100105090147_add_cost_price.rb | 9 + ...5132138_shipment_id_for_inventory_units.rb | 21 + ...100111205525_cim_fields_for_creditcards.rb | 11 + ...0112151511_create_return_authorizations.rb | 16 + ...return_authorization_to_inventory_units.rb | 9 + .../migrate/20100113203104_create_trackers.rb | 14 + ...60010_creditcard_id_for_creditcard_txns.rb | 9 + ...l_creditcard_txn_id_for_creditcard_txns.rb | 9 + ...51_add_test_mode_to_billing_integration.rb | 11 + ...26103714_create_products_product_groups.rb | 12 + .../20100209025806_create_payment_methods.rb | 20 + .../20100209144531_polymorphic_payments.rb | 29 + ...e_payments_payment_method_to_belongs_to.rb | 11 + ...12536_assign_creditcard_txns_to_payment.rb | 16 + .../20100223170312_sti_for_transactions.rb | 14 + ...0100223183812_drop_billing_integrations.rb | 16 + ...24153127_deleted_at_for_payment_methods.rb | 13 + .../20100301163454_add_adjustments_index.rb | 10 + .../20100306153445_fix_by_popularity.rb | 8 + .../20100317120946_add_alt_text_to_images.rb | 9 + ...27121301_add_display_to_payment_methods.rb | 9 + ...4142133_add_addresses_checkouts_indexes.rb | 16 + .../20100506180619_add_icon_to_taxons.rb | 18 + ...0100506185838_add_description_to_taxons.rb | 11 + ...100528155333_index_for_shipments_number.rb | 9 + ...20_add_index_on_users_persistence_token.rb | 9 + ...605152042_add_default_to_tax_categories.rb | 9 + ...4110730_add_display_to_shipping_methods.rb | 9 + ...624123336_rename_payment_method_display.rb | 9 + ...20100624175547_rename_preferences_field.rb | 8 + .../migrate/20100811163637_add_guest_flag.rb | 13 + .../20100811205836_drop_order_token.rb | 11 + ...yments_state_and_assigned_to_order_only.rb | 11 + ...813023502_create_address_keys_for_order.rb | 15 + ...20100813185745_payment_total_for_orders.rb | 9 + ...816212146_shipping_method_id_for_orders.rb | 9 + ...17152723_add_shipment_and_payment_state.rb | 15 + .../20100819170125_refactor_adjustments.rb | 19 + ...onse_code_and_avs_response_for_payments.rb | 11 + ...01171814_change_guest_flag_to_anonymous.rb | 13 + .../20100903203949_email_for_orders.rb | 9 + .../20100923162011_create_mail_methods.rb | 12 + .../20100929151905_rename_frozen_to_locked.rb | 8 + ...536_move_special_instructions_to_orders.rb | 11 + .../20101026184700_create_log_entries.rb | 15 + ...4_migrate_transactions_to_payment_state.rb | 94 + ...0101026184746_delete_in_progress_orders.rb | 18 + ...101026184808_migrate_checkout_to_orders.rb | 27 + .../20101026184833_migrate_adjustments.rb | 9 + .../20101026184855_remove_shipped_state.rb | 14 + ...0101026184916_prevent_nil_payment_total.rb | 8 + .../20101026184932_prevent_nil_email.rb | 9 + ...20101026184959_generate_anonymous_users.rb | 14 + .../20101026185022_update_order_state.rb | 8 + .../20101026192225_cleanup_legacy_tables.rb | 11 + ...45_remove_number_and_cvv_from_credicard.rb | 9 + ...103212716_drop_anonymous_field_for_user.rb | 8 + ...01111133551_renamed_rma_cancelled_state.rb | 10 + ...01117031806_fix_problematic_index_names.rb | 13 + spec/test_app/db/sample/users.rb | 53 + spec/test_app/db/schema.rb | 543 +++ spec/test_app/db/seeds.rb | 3 + spec/test_app/db/test.sqlite3 | Bin 0 -> 137216 bytes spec/test_app/log/cucumber.log | 1309 ++++++ spec/test_app/log/development.log | 35 + .../test_app/log/production.log | 0 spec/test_app/log/server.log | 0 spec/test_app/log/test.log | 3675 +++++++++++++++++ spec/test_app/public/404.html | 26 + spec/test_app/public/422.html | 26 + spec/test_app/public/500.html | 26 + spec/test_app/public/favicon.ico | 0 spec/test_app/public/images/add-to-cart.png | Bin 0 -> 1157 bytes .../public/images/admin/bg/active-tab.png | Bin 0 -> 218 bytes .../public/images/admin/bg/admin_tab_back.png | Bin 0 -> 148 bytes .../admin/bg/admin_tab_selected_back.png | Bin 0 -> 142 bytes .../images/admin/bg/content-back-blue.png | Bin 0 -> 259 bytes .../images/admin/bg/content-back-green.png | Bin 0 -> 238 bytes .../public/images/admin/bg/content-back.png | Bin 0 -> 181 bytes .../public/images/admin/bg/flash-error.png | Bin 0 -> 1784 bytes .../public/images/admin/bg/flash-notice.png | Bin 0 -> 1887 bytes .../public/images/admin/bg/green-stripes.gif | Bin 0 -> 50 bytes .../public/images/admin/bg/green-stripes.png | Bin 0 -> 199 bytes .../images/admin/bg/grid_header_back.png | Bin 0 -> 148 bytes .../admin/bg/grid_header_back_green.png | Bin 0 -> 169 bytes .../public/images/admin/bg/header-bg.png | Bin 0 -> 1235 bytes .../public/images/admin/bg/header.png | Bin 0 -> 132 bytes .../public/images/admin/bg/header_bg.jpg | Bin 0 -> 5418 bytes .../public/images/admin/bg/menu-current.png | Bin 0 -> 715 bytes .../public/images/admin/bg/red-stripes.gif | Bin 0 -> 50 bytes .../public/images/admin/bg/red-stripes.png | Bin 0 -> 200 bytes .../public/images/admin/bg/spree_50.png | Bin 0 -> 3349 bytes .../public/images/admin/bg/subnav-divider.png | Bin 0 -> 206 bytes .../public/images/admin/bg/subnav.png | Bin 0 -> 204 bytes .../public/images/admin/bg/tab-back.png | Bin 0 -> 3635 bytes .../images/admin/buttons/blue/left_01.png | Bin 0 -> 767 bytes .../images/admin/buttons/blue/right_01.png | Bin 0 -> 416 bytes .../admin/buttons/drag-handle-green.png | Bin 0 -> 160 bytes .../images/admin/buttons/green/left_01.png | Bin 0 -> 717 bytes .../images/admin/buttons/green/right_01.png | Bin 0 -> 412 bytes .../public/images/admin/buttons/left_01.png | Bin 0 -> 536 bytes .../images/admin/buttons/left_01_small.png | Bin 0 -> 404 bytes .../images/admin/buttons/orange/left_03.png | Bin 0 -> 1885 bytes .../images/admin/buttons/orange/right_03.png | Bin 0 -> 679 bytes .../public/images/admin/buttons/right_01.png | Bin 0 -> 397 bytes .../images/admin/buttons/right_01_small.png | Bin 0 -> 415 bytes .../public/images/admin/icons/16x16/1.png | Bin 0 -> 942 bytes .../public/images/admin/icons/16x16/10.png | Bin 0 -> 895 bytes .../public/images/admin/icons/16x16/2.png | Bin 0 -> 871 bytes .../public/images/admin/icons/16x16/3.png | Bin 0 -> 907 bytes .../public/images/admin/icons/16x16/4.png | Bin 0 -> 885 bytes .../public/images/admin/icons/16x16/5.png | Bin 0 -> 910 bytes .../public/images/admin/icons/16x16/6.png | Bin 0 -> 915 bytes .../public/images/admin/icons/16x16/7.png | Bin 0 -> 910 bytes .../public/images/admin/icons/16x16/8.png | Bin 0 -> 910 bytes .../public/images/admin/icons/16x16/9.png | Bin 0 -> 896 bytes .../public/images/admin/icons/32x32/1.png | Bin 0 -> 2241 bytes .../public/images/admin/icons/32x32/10.png | Bin 0 -> 2174 bytes .../public/images/admin/icons/32x32/11.png | Bin 0 -> 2327 bytes .../public/images/admin/icons/32x32/2.png | Bin 0 -> 2065 bytes .../public/images/admin/icons/32x32/3.png | Bin 0 -> 2203 bytes .../public/images/admin/icons/32x32/4.png | Bin 0 -> 2206 bytes .../public/images/admin/icons/32x32/5.png | Bin 0 -> 2245 bytes .../public/images/admin/icons/32x32/6.png | Bin 0 -> 2296 bytes .../public/images/admin/icons/32x32/7.png | Bin 0 -> 2171 bytes .../public/images/admin/icons/32x32/8.png | Bin 0 -> 2154 bytes .../public/images/admin/icons/32x32/9.png | Bin 0 -> 2170 bytes .../public/images/admin/icons/accept.png | Bin 0 -> 781 bytes .../public/images/admin/icons/add.gif | Bin 0 -> 119 bytes .../public/images/admin/icons/add.png | Bin 0 -> 733 bytes .../public/images/admin/icons/arrow-down.gif | Bin 0 -> 80 bytes .../public/images/admin/icons/cross.png | Bin 0 -> 655 bytes .../public/images/admin/icons/delete.gif | Bin 0 -> 181 bytes .../public/images/admin/icons/delete.png | Bin 0 -> 655 bytes .../public/images/admin/icons/drag.gif | Bin 0 -> 88 bytes .../public/images/admin/icons/edit.gif | Bin 0 -> 119 bytes .../public/images/admin/icons/edit.png | Bin 0 -> 450 bytes .../public/images/admin/icons/email.png | Bin 0 -> 641 bytes .../public/images/admin/icons/error.png | Bin 0 -> 666 bytes .../public/images/admin/icons/exclamation.png | Bin 0 -> 701 bytes .../public/images/admin/icons/feed.png | Bin 0 -> 691 bytes .../public/images/admin/icons/pdf.png | Bin 0 -> 591 bytes .../public/images/admin/icons/reorder.gif | Bin 0 -> 84 bytes .../public/images/admin/icons/search.gif | Bin 0 -> 552 bytes .../public/images/admin/icons/send-email.png | Bin 0 -> 754 bytes .../public/images/admin/icons/stop.png | Bin 0 -> 715 bytes .../public/images/admin/icons/tick.png | Bin 0 -> 537 bytes .../test_app/public/images/admin/icons/up.gif | Bin 0 -> 838 bytes .../public/images/admin/icons/xls.png | Bin 0 -> 663 bytes .../public/images/admin/tabs/off-left.png | Bin 0 -> 357 bytes .../public/images/admin/tabs/off-right.png | Bin 0 -> 296 bytes .../public/images/admin/tabs/on-left.png | Bin 0 -> 422 bytes .../public/images/admin/tabs/on-right.png | Bin 0 -> 352 bytes spec/test_app/public/images/ajax_loader.gif | Bin 0 -> 1849 bytes spec/test_app/public/images/amex_cid.gif | Bin 0 -> 41739 bytes .../public/images/bg-button-hover.png | Bin 0 -> 171 bytes .../public/images/bg-button-pressed.png | Bin 0 -> 155 bytes spec/test_app/public/images/bg-button.gif | Bin 0 -> 410 bytes spec/test_app/public/images/bg-button.png | Bin 0 -> 170 bytes spec/test_app/public/images/blue/left_01.png | Bin 0 -> 767 bytes spec/test_app/public/images/blue/right_01.png | Bin 0 -> 416 bytes spec/test_app/public/images/body-back.png | Bin 0 -> 254 bytes spec/test_app/public/images/bottom_shine.png | Bin 0 -> 828 bytes spec/test_app/public/images/breadcrumb.gif | Bin 0 -> 58 bytes .../public/images/button-dark-hover.png | Bin 0 -> 173 bytes spec/test_app/public/images/button-dark.png | Bin 0 -> 166 bytes .../public/images/buttons/bg-button-hover.png | Bin 0 -> 171 bytes .../images/buttons/bg-button-pressed.png | Bin 0 -> 155 bytes .../public/images/buttons/bg-button.gif | Bin 0 -> 410 bytes .../public/images/buttons/bg-button.png | Bin 0 -> 170 bytes .../public/images/buttons/blue/left_01.png | Bin 0 -> 767 bytes .../public/images/buttons/blue/right_01.png | Bin 0 -> 416 bytes .../images/buttons/button-dark-hover.png | Bin 0 -> 173 bytes .../public/images/buttons/button-dark.png | Bin 0 -> 166 bytes .../images/buttons/drag-handle-green.png | Bin 0 -> 160 bytes .../public/images/buttons/green/left_01.png | Bin 0 -> 717 bytes .../public/images/buttons/green/right_01.png | Bin 0 -> 412 bytes .../public/images/buttons/left_01.png | Bin 0 -> 536 bytes .../public/images/buttons/left_01_small.png | Bin 0 -> 607 bytes .../public/images/buttons/orange/left_03.png | Bin 0 -> 1885 bytes .../public/images/buttons/orange/right_03.png | Bin 0 -> 679 bytes .../public/images/buttons/right_01.png | Bin 0 -> 397 bytes .../public/images/buttons/right_01_small.png | Bin 0 -> 451 bytes .../public/images/buttons/sxsw-ribbon-v1.png | Bin 0 -> 4864 bytes .../public/images/buttons/top-shine.png | Bin 0 -> 819 bytes .../images/calendar_date_select/calendar.gif | Bin 0 -> 581 bytes spec/test_app/public/images/cart-empty.png | Bin 0 -> 3254 bytes .../test_app/public/images/cart-empty_x32.png | Bin 0 -> 2035 bytes spec/test_app/public/images/cart-full.png | Bin 0 -> 4074 bytes spec/test_app/public/images/cart-full_x32.png | Bin 0 -> 2371 bytes spec/test_app/public/images/checkout.png | Bin 0 -> 794 bytes spec/test_app/public/images/creditcard.gif | Bin 0 -> 2668 bytes .../public/images/datepicker/backstripes.gif | Bin 0 -> 234 bytes .../public/images/datepicker/bg_header.jpg | Bin 0 -> 1792 bytes .../public/images/datepicker/bullet1.gif | Bin 0 -> 55 bytes .../public/images/datepicker/bullet2.gif | Bin 0 -> 262 bytes .../test_app/public/images/datepicker/cal.gif | Bin 0 -> 127 bytes .../datepicker/gradient-e5e5e5-ffffff.gif | Bin 0 -> 526 bytes spec/test_app/public/images/discover_cid.gif | Bin 0 -> 2627 bytes .../public/images/drag-handle-green.png | Bin 0 -> 160 bytes spec/test_app/public/images/favicon.ico | Bin 0 -> 1150 bytes spec/test_app/public/images/green/left_01.png | Bin 0 -> 717 bytes .../test_app/public/images/green/right_01.png | Bin 0 -> 412 bytes spec/test_app/public/images/grid.png | Bin 0 -> 206 bytes spec/test_app/public/images/left_01.png | Bin 0 -> 536 bytes spec/test_app/public/images/left_01_small.png | Bin 0 -> 607 bytes spec/test_app/public/images/master_cid.jpg | Bin 0 -> 11171 bytes spec/test_app/public/images/menu-current.png | Bin 0 -> 3475 bytes spec/test_app/public/images/menu-hover.png | Bin 0 -> 6007 bytes spec/test_app/public/images/noimage/mini.jpg | Bin 0 -> 2013 bytes .../public/images/noimage/product.jpg | Bin 0 -> 16044 bytes spec/test_app/public/images/noimage/small.jpg | Bin 0 -> 5175 bytes .../public/images/openid-inputicon.gif | Bin 0 -> 237 bytes .../test_app/public/images/orange/left_03.png | Bin 0 -> 1885 bytes .../public/images/orange/right_03.png | Bin 0 -> 679 bytes spec/test_app/public/images/progress.gif | Bin 0 -> 3208 bytes spec/test_app/public/images/right_01.png | Bin 0 -> 397 bytes .../test_app/public/images/right_01_small.png | Bin 0 -> 451 bytes spec/test_app/public/images/separator.png | Bin 0 -> 517 bytes spec/test_app/public/images/shadow-top.png | Bin 0 -> 153 bytes spec/test_app/public/images/shadow_top.png | Bin 0 -> 406 bytes spec/test_app/public/images/spinner.gif | Bin 0 -> 1608 bytes spec/test_app/public/images/spree.jpg | Bin 0 -> 18400 bytes .../test_app/public/images/spree/progress.gif | Bin 0 -> 530 bytes spec/test_app/public/images/spree/spinner.gif | Bin 0 -> 1105 bytes spec/test_app/public/images/spree/spree.jpg | Bin 0 -> 18400 bytes .../step-progress/completed-completed.gif | Bin 0 -> 295 bytes .../step-progress/completed-current.gif | Bin 0 -> 324 bytes .../images/step-progress/completed-first.gif | Bin 0 -> 148 bytes .../images/step-progress/current-first.gif | Bin 0 -> 148 bytes .../step-progress/current-incomplete.gif | Bin 0 -> 319 bytes .../images/step-progress/current-right.gif | Bin 0 -> 131 bytes .../step-progress/incomplete-incomplete.gif | Bin 0 -> 278 bytes .../images/step-progress/incomplete-right.gif | Bin 0 -> 108 bytes spec/test_app/public/images/steps/1.png | Bin 0 -> 3617 bytes spec/test_app/public/images/steps/1_small.png | Bin 0 -> 1082 bytes spec/test_app/public/images/steps/2.png | Bin 0 -> 4803 bytes spec/test_app/public/images/steps/2_small.png | Bin 0 -> 993 bytes spec/test_app/public/images/steps/3.png | Bin 0 -> 6184 bytes spec/test_app/public/images/steps/3_small.png | Bin 0 -> 1189 bytes spec/test_app/public/images/steps/4.png | Bin 0 -> 2338 bytes spec/test_app/public/images/steps/4_small.png | Bin 0 -> 967 bytes spec/test_app/public/images/steps/5.png | Bin 0 -> 3015 bytes spec/test_app/public/images/steps/5_small.png | Bin 0 -> 1133 bytes spec/test_app/public/images/steps/6.png | Bin 0 -> 3596 bytes spec/test_app/public/images/steps/6_small.png | Bin 0 -> 1438 bytes .../test_app/public/images/sxsw-ribbon-v1.png | Bin 0 -> 4864 bytes spec/test_app/public/images/tab_bottom.gif | Bin 0 -> 43 bytes spec/test_app/public/images/tile-header.png | Bin 0 -> 153 bytes spec/test_app/public/images/tile-slider.png | Bin 0 -> 193 bytes spec/test_app/public/images/top-shine.png | Bin 0 -> 819 bytes .../public/images/tree-nav-icons/bullet.gif | Bin 0 -> 62 bytes .../public/images/tree-nav-icons/minus.gif | Bin 0 -> 87 bytes .../public/images/tree-nav-icons/plus.gif | Bin 0 -> 89 bytes .../tree-nav-icons/treeview-loading.gif | Bin 0 -> 2673 bytes .../images/tree-nav-icons/treeview-sprite.gif | Bin 0 -> 3900 bytes spec/test_app/public/images/update.png | Bin 0 -> 793 bytes spec/test_app/public/images/visa_cid.gif | Bin 0 -> 10483 bytes .../test_app/public/images/wrapper-back-2.png | Bin 0 -> 41226 bytes spec/test_app/public/images/wrapper-back.png | Bin 0 -> 41748 bytes .../yui-menubaritem_submenuindicator.png | Bin 0 -> 3618 bytes ...-menubaritem_submenuindicator_disabled.png | Bin 0 -> 3618 bytes .../public/images/yui-menuitem_checkbox.png | Bin 0 -> 3625 bytes .../images/yui-menuitem_checkbox_disabled.png | Bin 0 -> 3625 bytes .../images/yui-menuitem_submenuindicator.png | Bin 0 -> 3617 bytes ...yui-menuitem_submenuindicator_disabled.png | Bin 0 -> 3617 bytes spec/test_app/public/images/yui-sprite.png | Bin 0 -> 3123 bytes .../public/javascripts/additional-methods.js | 236 ++ spec/test_app/public/javascripts/admin.js | 226 + .../javascripts/admin/address_states.js | 25 + .../javascripts/admin/checkouts/edit.js | 129 + .../public/javascripts/admin/orders/edit.js | 23 + .../javascripts/admin/orders/edit_form.js | 15 + .../public/javascripts/admin/payments/new.js | 9 + .../javascripts/admin/unobtrusive_handlers.js | 15 + .../public/javascripts/application.js | 12 + .../test_app/public/javascripts/calculator.js | 15 + spec/test_app/public/javascripts/checkout.js | 75 + .../test_app/public/javascripts/datepicker.js | 1445 +++++++ spec/test_app/public/javascripts/gateway.js | 13 + .../public/javascripts/jquery-1.4.2.min.js | 154 + spec/test_app/public/javascripts/jquery-ui.js | 188 + .../javascripts/jquery.alerts/images/help.gif | Bin 0 -> 1582 bytes .../jquery.alerts/images/important.gif | Bin 0 -> 1492 bytes .../javascripts/jquery.alerts/images/info.gif | Bin 0 -> 1487 bytes .../jquery.alerts/images/title.gif | Bin 0 -> 317 bytes .../jquery.alerts/jquery.alerts.css | 57 + .../jquery.alerts/jquery.alerts.js | 235 ++ .../jquery.alerts/jquery.alerts.spree.css | 30 + .../javascripts/jquery.autocomplete.min.js | 13 + spec/test_app/public/javascripts/jquery.js | 19 + .../public/javascripts/jquery.suggest.js | 276 ++ .../public/javascripts/jquery.template.js | 255 ++ .../public/javascripts/jquery.tokeninput.js | 618 +++ .../public/javascripts/jquery.validate.min.js | 16 + .../public/javascripts/jrails.autocomplete.js | 274 ++ spec/test_app/public/javascripts/jrails.js | 1 + .../public/javascripts/jsTree/jquery.tree.js | 2058 +++++++++ .../jsTree/plugins/jquery.tree.contextmenu.js | 129 + .../javascripts/jsTree/themes/apple/bg.jpg | Bin 0 -> 331 bytes .../jsTree/themes/apple/dot_for_ie.gif | Bin 0 -> 43 bytes .../javascripts/jsTree/themes/apple/icons.png | Bin 0 -> 5951 bytes .../javascripts/jsTree/themes/apple/style.css | 34 + .../jsTree/themes/apple/throbber.gif | Bin 0 -> 1844 bytes spec/test_app/public/javascripts/lang/af.js | 40 + spec/test_app/public/javascripts/lang/ar.js | 50 + spec/test_app/public/javascripts/lang/de.js | 40 + spec/test_app/public/javascripts/lang/du.js | 40 + spec/test_app/public/javascripts/lang/en.js | 42 + spec/test_app/public/javascripts/lang/es.js | 41 + spec/test_app/public/javascripts/lang/fi.js | 40 + spec/test_app/public/javascripts/lang/fr.js | 44 + spec/test_app/public/javascripts/lang/gr.js | 40 + spec/test_app/public/javascripts/lang/he.js | 49 + spec/test_app/public/javascripts/lang/it.js | 13 + spec/test_app/public/javascripts/lang/nl.js | 40 + spec/test_app/public/javascripts/lang/no.js | 40 + spec/test_app/public/javascripts/lang/pt.js | 50 + spec/test_app/public/javascripts/lang/ro.js | 40 + spec/test_app/public/javascripts/lang/ru.js | 40 + spec/test_app/public/javascripts/lang/sp.js | 40 + spec/test_app/public/javascripts/lang/sv.js | 41 + spec/test_app/public/javascripts/lang/ua.js | 40 + .../javascripts/localization/messages_cn.js | 24 + .../javascripts/localization/messages_cs.js | 23 + .../javascripts/localization/messages_da.js | 21 + .../javascripts/localization/messages_de.js | 21 + .../javascripts/localization/messages_es.js | 24 + .../javascripts/localization/messages_fr.js | 23 + .../javascripts/localization/messages_hu.js | 21 + .../javascripts/localization/messages_it.js | 26 + .../javascripts/localization/messages_kk.js | 23 + .../javascripts/localization/messages_nl.js | 23 + .../javascripts/localization/messages_no.js | 23 + .../javascripts/localization/messages_pl.js | 23 + .../javascripts/localization/messages_ptbr.js | 30 + .../javascripts/localization/messages_ro.js | 24 + .../javascripts/localization/messages_ru.js | 23 + .../javascripts/localization/messages_se.js | 23 + .../javascripts/localization/messages_sk.js | 21 + .../javascripts/localization/messages_tr.js | 24 + .../javascripts/localization/messages_tw.js | 24 + .../javascripts/localization/messages_ua.js | 24 + .../public/javascripts/nested-attribute.js | 26 + spec/test_app/public/javascripts/open_id.js | 15 + spec/test_app/public/javascripts/product.js | 49 + spec/test_app/public/javascripts/rails.js | 127 + spec/test_app/public/javascripts/taxonomy.js | 196 + spec/test_app/public/javascripts/zone.js | 40 + spec/test_app/public/robots.txt | 5 + .../public/stylesheets/admin/admin-forms.css | 159 + .../public/stylesheets/admin/admin-reset.css | 67 + .../public/stylesheets/admin/admin-tables.css | 39 + .../stylesheets/admin/admin-typography.css | 117 + .../public/stylesheets/admin/admin.css | 579 +++ .../public/stylesheets/admin/autocomplete.css | 73 + .../public/stylesheets/admin/dashboard.css | 143 + .../stylesheets/admin/edit_checkouts.css | 57 + .../public/stylesheets/admin/grids.css | 314 ++ .../admin/reset-fonts-grids-2-6-0.css | 7 + .../public/stylesheets/admin/token-input.css | 109 + .../public/stylesheets/admin/yui-includes.css | 14 + .../public/stylesheets/datepicker.css | 263 ++ .../stylesheets/jquery.autocomplete.css | 48 + spec/test_app/public/stylesheets/scaffold.css | 54 + spec/test_app/public/stylesheets/screen.css | 1195 ++++++ spec/test_app/script/rails | 6 + .../tmp/cache/588/EC0/Spree%3A%3AConfig | Bin 0 -> 985 bytes spree_faq.gemspec | 22 + 449 files changed, 21715 insertions(+), 318 deletions(-) create mode 100644 LICENSE rename README.markdown => README.md (64%) delete mode 100644 app/helpers/admin/question_categories_helper.rb delete mode 100644 app/helpers/faqs_helper.rb create mode 100644 autotest/discover.rb delete mode 100644 db/sample/question_categories.yml delete mode 100644 db/sample/questions.yml delete mode 100644 faq_extension.rb delete mode 100644 faq_hooks.rb create mode 100644 lib/generators/spree_faq/install_generator.rb rename {db => lib/generators/templates/db}/migrate/20090526213535_create_questions.rb (100%) rename {db => lib/generators/templates/db}/migrate/20090526213550_create_question_categories.rb (100%) rename {public => lib/generators/templates/public}/javascripts/jquery.scrollTo-min.js (100%) rename {public => lib/generators/templates/public}/stylesheets/spree_faq.css (100%) create mode 100644 lib/spree_faq.rb create mode 100644 lib/spree_faq/engine.rb create mode 100644 lib/spree_faq_hooks.rb delete mode 100644 lib/tasks/faq_extension_tasks.rake delete mode 100644 spec/helpers/admin/question_categories_helper_spec.rb delete mode 100644 spec/helpers/faqs_helper_spec.rb create mode 100644 spec/test_app/Gemfile create mode 100644 spec/test_app/Gemfile.lock create mode 100644 spec/test_app/Rakefile create mode 100644 spec/test_app/app/controllers/application_controller.rb create mode 100644 spec/test_app/app/helpers/application_helper.rb create mode 100644 spec/test_app/app/views/layouts/application.html.erb create mode 100644 spec/test_app/config.ru create mode 100644 spec/test_app/config/application.rb create mode 100644 spec/test_app/config/boot.rb create mode 100644 spec/test_app/config/database.yml create mode 100644 spec/test_app/config/environment.rb create mode 100644 spec/test_app/config/environments/cucumber.rb create mode 100644 spec/test_app/config/environments/development.rb create mode 100644 spec/test_app/config/environments/production.rb create mode 100644 spec/test_app/config/environments/test.rb create mode 100644 spec/test_app/config/initializers/backtrace_silencers.rb create mode 100644 spec/test_app/config/initializers/inflections.rb create mode 100644 spec/test_app/config/initializers/mime_types.rb create mode 100644 spec/test_app/config/initializers/secret_token.rb create mode 100644 spec/test_app/config/initializers/session_store.rb create mode 100644 spec/test_app/config/locales/en.yml create mode 100644 spec/test_app/config/routes.rb create mode 100644 spec/test_app/db/cucumber.sqlite3 create mode 100644 spec/test_app/db/default/countries.yml create mode 100644 spec/test_app/db/default/roles.yml create mode 100644 spec/test_app/db/default/states.yml create mode 100644 spec/test_app/db/default/zone_members.yml create mode 100644 spec/test_app/db/default/zones.yml create mode 100644 spec/test_app/db/migrate/20090526213535_create_questions.rb create mode 100644 spec/test_app/db/migrate/20090526213550_create_question_categories.rb create mode 100644 spec/test_app/db/migrate/20090823005402_spree_zero_nine_zero.rb create mode 100644 spec/test_app/db/migrate/20090904192342_create_indexes_for_inventory_units.rb create mode 100644 spec/test_app/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb create mode 100644 spec/test_app/db/migrate/20091007134354_change_taxons_to_nested_set.rb create mode 100644 spec/test_app/db/migrate/20091008091614_move_to_configurable_gateways.rb create mode 100644 spec/test_app/db/migrate/20091012120519_product_groups_and_scopes.rb create mode 100644 spec/test_app/db/migrate/20091015110842_add_open_id_authentication_tables.rb create mode 100644 spec/test_app/db/migrate/20091015153048_add_openid_field_to_users.rb create mode 100644 spec/test_app/db/migrate/20091016174634_change_preference_value_type.rb create mode 100644 spec/test_app/db/migrate/20091017175558_create_billing_integrations.rb create mode 100644 spec/test_app/db/migrate/20091021133257_charge_refactoring.rb create mode 100644 spec/test_app/db/migrate/20091104151730_add_some_indexes.rb create mode 100644 spec/test_app/db/migrate/20091126190904_checkout_state_machine.rb create mode 100644 spec/test_app/db/migrate/20091209153045_state_for_shipments.rb create mode 100644 spec/test_app/db/migrate/20091209202200_make_state_events_polymorphic.rb create mode 100644 spec/test_app/db/migrate/20091211203813_ship_address_id_for_checkouts.rb create mode 100644 spec/test_app/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb create mode 100644 spec/test_app/db/migrate/20091213222815_creditcard_last_four_digits.rb create mode 100644 spec/test_app/db/migrate/20091214183826_populate_legacy_shipment_state.rb create mode 100644 spec/test_app/db/migrate/20100105090147_add_cost_price.rb create mode 100644 spec/test_app/db/migrate/20100105132138_shipment_id_for_inventory_units.rb create mode 100644 spec/test_app/db/migrate/20100111205525_cim_fields_for_creditcards.rb create mode 100644 spec/test_app/db/migrate/20100112151511_create_return_authorizations.rb create mode 100644 spec/test_app/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb create mode 100644 spec/test_app/db/migrate/20100113203104_create_trackers.rb create mode 100644 spec/test_app/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb create mode 100644 spec/test_app/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb create mode 100644 spec/test_app/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb create mode 100644 spec/test_app/db/migrate/20100126103714_create_products_product_groups.rb create mode 100644 spec/test_app/db/migrate/20100209025806_create_payment_methods.rb create mode 100644 spec/test_app/db/migrate/20100209144531_polymorphic_payments.rb create mode 100644 spec/test_app/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb create mode 100644 spec/test_app/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb create mode 100644 spec/test_app/db/migrate/20100223170312_sti_for_transactions.rb create mode 100644 spec/test_app/db/migrate/20100223183812_drop_billing_integrations.rb create mode 100644 spec/test_app/db/migrate/20100224153127_deleted_at_for_payment_methods.rb create mode 100644 spec/test_app/db/migrate/20100301163454_add_adjustments_index.rb create mode 100644 spec/test_app/db/migrate/20100306153445_fix_by_popularity.rb create mode 100644 spec/test_app/db/migrate/20100317120946_add_alt_text_to_images.rb create mode 100644 spec/test_app/db/migrate/20100427121301_add_display_to_payment_methods.rb create mode 100755 spec/test_app/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb create mode 100644 spec/test_app/db/migrate/20100506180619_add_icon_to_taxons.rb create mode 100644 spec/test_app/db/migrate/20100506185838_add_description_to_taxons.rb create mode 100644 spec/test_app/db/migrate/20100528155333_index_for_shipments_number.rb create mode 100644 spec/test_app/db/migrate/20100528185820_add_index_on_users_persistence_token.rb create mode 100644 spec/test_app/db/migrate/20100605152042_add_default_to_tax_categories.rb create mode 100644 spec/test_app/db/migrate/20100624110730_add_display_to_shipping_methods.rb create mode 100644 spec/test_app/db/migrate/20100624123336_rename_payment_method_display.rb create mode 100644 spec/test_app/db/migrate/20100624175547_rename_preferences_field.rb create mode 100644 spec/test_app/db/migrate/20100811163637_add_guest_flag.rb create mode 100644 spec/test_app/db/migrate/20100811205836_drop_order_token.rb create mode 100644 spec/test_app/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb create mode 100644 spec/test_app/db/migrate/20100813023502_create_address_keys_for_order.rb create mode 100644 spec/test_app/db/migrate/20100813185745_payment_total_for_orders.rb create mode 100644 spec/test_app/db/migrate/20100816212146_shipping_method_id_for_orders.rb create mode 100644 spec/test_app/db/migrate/20100817152723_add_shipment_and_payment_state.rb create mode 100644 spec/test_app/db/migrate/20100819170125_refactor_adjustments.rb create mode 100644 spec/test_app/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb create mode 100644 spec/test_app/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb create mode 100644 spec/test_app/db/migrate/20100903203949_email_for_orders.rb create mode 100644 spec/test_app/db/migrate/20100923162011_create_mail_methods.rb create mode 100644 spec/test_app/db/migrate/20100929151905_rename_frozen_to_locked.rb create mode 100644 spec/test_app/db/migrate/20101008190536_move_special_instructions_to_orders.rb create mode 100644 spec/test_app/db/migrate/20101026184700_create_log_entries.rb create mode 100644 spec/test_app/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb create mode 100644 spec/test_app/db/migrate/20101026184746_delete_in_progress_orders.rb create mode 100644 spec/test_app/db/migrate/20101026184808_migrate_checkout_to_orders.rb create mode 100644 spec/test_app/db/migrate/20101026184833_migrate_adjustments.rb create mode 100644 spec/test_app/db/migrate/20101026184855_remove_shipped_state.rb create mode 100644 spec/test_app/db/migrate/20101026184916_prevent_nil_payment_total.rb create mode 100644 spec/test_app/db/migrate/20101026184932_prevent_nil_email.rb create mode 100644 spec/test_app/db/migrate/20101026184959_generate_anonymous_users.rb create mode 100644 spec/test_app/db/migrate/20101026185022_update_order_state.rb create mode 100644 spec/test_app/db/migrate/20101026192225_cleanup_legacy_tables.rb create mode 100644 spec/test_app/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb create mode 100644 spec/test_app/db/migrate/20101103212716_drop_anonymous_field_for_user.rb create mode 100644 spec/test_app/db/migrate/20101111133551_renamed_rma_cancelled_state.rb create mode 100644 spec/test_app/db/migrate/20101117031806_fix_problematic_index_names.rb create mode 100644 spec/test_app/db/sample/users.rb create mode 100644 spec/test_app/db/schema.rb create mode 100644 spec/test_app/db/seeds.rb create mode 100644 spec/test_app/db/test.sqlite3 create mode 100644 spec/test_app/log/cucumber.log create mode 100644 spec/test_app/log/development.log rename app/views/faqs/show.rjs => spec/test_app/log/production.log (100%) create mode 100644 spec/test_app/log/server.log create mode 100644 spec/test_app/log/test.log create mode 100644 spec/test_app/public/404.html create mode 100644 spec/test_app/public/422.html create mode 100644 spec/test_app/public/500.html create mode 100644 spec/test_app/public/favicon.ico create mode 100644 spec/test_app/public/images/add-to-cart.png create mode 100644 spec/test_app/public/images/admin/bg/active-tab.png create mode 100644 spec/test_app/public/images/admin/bg/admin_tab_back.png create mode 100644 spec/test_app/public/images/admin/bg/admin_tab_selected_back.png create mode 100644 spec/test_app/public/images/admin/bg/content-back-blue.png create mode 100644 spec/test_app/public/images/admin/bg/content-back-green.png create mode 100644 spec/test_app/public/images/admin/bg/content-back.png create mode 100644 spec/test_app/public/images/admin/bg/flash-error.png create mode 100644 spec/test_app/public/images/admin/bg/flash-notice.png create mode 100644 spec/test_app/public/images/admin/bg/green-stripes.gif create mode 100644 spec/test_app/public/images/admin/bg/green-stripes.png create mode 100644 spec/test_app/public/images/admin/bg/grid_header_back.png create mode 100644 spec/test_app/public/images/admin/bg/grid_header_back_green.png create mode 100644 spec/test_app/public/images/admin/bg/header-bg.png create mode 100644 spec/test_app/public/images/admin/bg/header.png create mode 100755 spec/test_app/public/images/admin/bg/header_bg.jpg create mode 100644 spec/test_app/public/images/admin/bg/menu-current.png create mode 100644 spec/test_app/public/images/admin/bg/red-stripes.gif create mode 100644 spec/test_app/public/images/admin/bg/red-stripes.png create mode 100644 spec/test_app/public/images/admin/bg/spree_50.png create mode 100644 spec/test_app/public/images/admin/bg/subnav-divider.png create mode 100644 spec/test_app/public/images/admin/bg/subnav.png create mode 100644 spec/test_app/public/images/admin/bg/tab-back.png create mode 100644 spec/test_app/public/images/admin/buttons/blue/left_01.png create mode 100644 spec/test_app/public/images/admin/buttons/blue/right_01.png create mode 100644 spec/test_app/public/images/admin/buttons/drag-handle-green.png create mode 100644 spec/test_app/public/images/admin/buttons/green/left_01.png create mode 100644 spec/test_app/public/images/admin/buttons/green/right_01.png create mode 100644 spec/test_app/public/images/admin/buttons/left_01.png create mode 100644 spec/test_app/public/images/admin/buttons/left_01_small.png create mode 100644 spec/test_app/public/images/admin/buttons/orange/left_03.png create mode 100644 spec/test_app/public/images/admin/buttons/orange/right_03.png create mode 100644 spec/test_app/public/images/admin/buttons/right_01.png create mode 100644 spec/test_app/public/images/admin/buttons/right_01_small.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/1.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/10.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/2.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/3.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/4.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/5.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/6.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/7.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/8.png create mode 100644 spec/test_app/public/images/admin/icons/16x16/9.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/1.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/10.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/11.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/2.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/3.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/4.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/5.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/6.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/7.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/8.png create mode 100644 spec/test_app/public/images/admin/icons/32x32/9.png create mode 100755 spec/test_app/public/images/admin/icons/accept.png create mode 100644 spec/test_app/public/images/admin/icons/add.gif create mode 100755 spec/test_app/public/images/admin/icons/add.png create mode 100644 spec/test_app/public/images/admin/icons/arrow-down.gif create mode 100755 spec/test_app/public/images/admin/icons/cross.png create mode 100644 spec/test_app/public/images/admin/icons/delete.gif create mode 100755 spec/test_app/public/images/admin/icons/delete.png create mode 100644 spec/test_app/public/images/admin/icons/drag.gif create mode 100644 spec/test_app/public/images/admin/icons/edit.gif create mode 100755 spec/test_app/public/images/admin/icons/edit.png create mode 100755 spec/test_app/public/images/admin/icons/email.png create mode 100755 spec/test_app/public/images/admin/icons/error.png create mode 100755 spec/test_app/public/images/admin/icons/exclamation.png create mode 100755 spec/test_app/public/images/admin/icons/feed.png create mode 100755 spec/test_app/public/images/admin/icons/pdf.png create mode 100644 spec/test_app/public/images/admin/icons/reorder.gif create mode 100644 spec/test_app/public/images/admin/icons/search.gif create mode 100755 spec/test_app/public/images/admin/icons/send-email.png create mode 100755 spec/test_app/public/images/admin/icons/stop.png create mode 100755 spec/test_app/public/images/admin/icons/tick.png create mode 100644 spec/test_app/public/images/admin/icons/up.gif create mode 100755 spec/test_app/public/images/admin/icons/xls.png create mode 100644 spec/test_app/public/images/admin/tabs/off-left.png create mode 100644 spec/test_app/public/images/admin/tabs/off-right.png create mode 100644 spec/test_app/public/images/admin/tabs/on-left.png create mode 100644 spec/test_app/public/images/admin/tabs/on-right.png create mode 100644 spec/test_app/public/images/ajax_loader.gif create mode 100644 spec/test_app/public/images/amex_cid.gif create mode 100644 spec/test_app/public/images/bg-button-hover.png create mode 100644 spec/test_app/public/images/bg-button-pressed.png create mode 100755 spec/test_app/public/images/bg-button.gif create mode 100644 spec/test_app/public/images/bg-button.png create mode 100755 spec/test_app/public/images/blue/left_01.png create mode 100755 spec/test_app/public/images/blue/right_01.png create mode 100644 spec/test_app/public/images/body-back.png create mode 100755 spec/test_app/public/images/bottom_shine.png create mode 100644 spec/test_app/public/images/breadcrumb.gif create mode 100644 spec/test_app/public/images/button-dark-hover.png create mode 100644 spec/test_app/public/images/button-dark.png create mode 100644 spec/test_app/public/images/buttons/bg-button-hover.png create mode 100644 spec/test_app/public/images/buttons/bg-button-pressed.png create mode 100755 spec/test_app/public/images/buttons/bg-button.gif create mode 100644 spec/test_app/public/images/buttons/bg-button.png create mode 100755 spec/test_app/public/images/buttons/blue/left_01.png create mode 100755 spec/test_app/public/images/buttons/blue/right_01.png create mode 100644 spec/test_app/public/images/buttons/button-dark-hover.png create mode 100644 spec/test_app/public/images/buttons/button-dark.png create mode 100755 spec/test_app/public/images/buttons/drag-handle-green.png create mode 100755 spec/test_app/public/images/buttons/green/left_01.png create mode 100755 spec/test_app/public/images/buttons/green/right_01.png create mode 100755 spec/test_app/public/images/buttons/left_01.png create mode 100755 spec/test_app/public/images/buttons/left_01_small.png create mode 100755 spec/test_app/public/images/buttons/orange/left_03.png create mode 100755 spec/test_app/public/images/buttons/orange/right_03.png create mode 100755 spec/test_app/public/images/buttons/right_01.png create mode 100755 spec/test_app/public/images/buttons/right_01_small.png create mode 100644 spec/test_app/public/images/buttons/sxsw-ribbon-v1.png create mode 100644 spec/test_app/public/images/buttons/top-shine.png create mode 100644 spec/test_app/public/images/calendar_date_select/calendar.gif create mode 100644 spec/test_app/public/images/cart-empty.png create mode 100644 spec/test_app/public/images/cart-empty_x32.png create mode 100644 spec/test_app/public/images/cart-full.png create mode 100644 spec/test_app/public/images/cart-full_x32.png create mode 100644 spec/test_app/public/images/checkout.png create mode 100644 spec/test_app/public/images/creditcard.gif create mode 100644 spec/test_app/public/images/datepicker/backstripes.gif create mode 100644 spec/test_app/public/images/datepicker/bg_header.jpg create mode 100644 spec/test_app/public/images/datepicker/bullet1.gif create mode 100644 spec/test_app/public/images/datepicker/bullet2.gif create mode 100644 spec/test_app/public/images/datepicker/cal.gif create mode 100644 spec/test_app/public/images/datepicker/gradient-e5e5e5-ffffff.gif create mode 100644 spec/test_app/public/images/discover_cid.gif create mode 100755 spec/test_app/public/images/drag-handle-green.png create mode 100644 spec/test_app/public/images/favicon.ico create mode 100755 spec/test_app/public/images/green/left_01.png create mode 100755 spec/test_app/public/images/green/right_01.png create mode 100644 spec/test_app/public/images/grid.png create mode 100755 spec/test_app/public/images/left_01.png create mode 100755 spec/test_app/public/images/left_01_small.png create mode 100644 spec/test_app/public/images/master_cid.jpg create mode 100644 spec/test_app/public/images/menu-current.png create mode 100644 spec/test_app/public/images/menu-hover.png create mode 100644 spec/test_app/public/images/noimage/mini.jpg create mode 100644 spec/test_app/public/images/noimage/product.jpg create mode 100644 spec/test_app/public/images/noimage/small.jpg create mode 100644 spec/test_app/public/images/openid-inputicon.gif create mode 100755 spec/test_app/public/images/orange/left_03.png create mode 100755 spec/test_app/public/images/orange/right_03.png create mode 100644 spec/test_app/public/images/progress.gif create mode 100755 spec/test_app/public/images/right_01.png create mode 100755 spec/test_app/public/images/right_01_small.png create mode 100644 spec/test_app/public/images/separator.png create mode 100644 spec/test_app/public/images/shadow-top.png create mode 100755 spec/test_app/public/images/shadow_top.png create mode 100644 spec/test_app/public/images/spinner.gif create mode 100644 spec/test_app/public/images/spree.jpg create mode 100644 spec/test_app/public/images/spree/progress.gif create mode 100644 spec/test_app/public/images/spree/spinner.gif create mode 100644 spec/test_app/public/images/spree/spree.jpg create mode 100644 spec/test_app/public/images/step-progress/completed-completed.gif create mode 100644 spec/test_app/public/images/step-progress/completed-current.gif create mode 100644 spec/test_app/public/images/step-progress/completed-first.gif create mode 100644 spec/test_app/public/images/step-progress/current-first.gif create mode 100644 spec/test_app/public/images/step-progress/current-incomplete.gif create mode 100644 spec/test_app/public/images/step-progress/current-right.gif create mode 100644 spec/test_app/public/images/step-progress/incomplete-incomplete.gif create mode 100644 spec/test_app/public/images/step-progress/incomplete-right.gif create mode 100644 spec/test_app/public/images/steps/1.png create mode 100644 spec/test_app/public/images/steps/1_small.png create mode 100644 spec/test_app/public/images/steps/2.png create mode 100644 spec/test_app/public/images/steps/2_small.png create mode 100644 spec/test_app/public/images/steps/3.png create mode 100644 spec/test_app/public/images/steps/3_small.png create mode 100644 spec/test_app/public/images/steps/4.png create mode 100644 spec/test_app/public/images/steps/4_small.png create mode 100644 spec/test_app/public/images/steps/5.png create mode 100644 spec/test_app/public/images/steps/5_small.png create mode 100644 spec/test_app/public/images/steps/6.png create mode 100644 spec/test_app/public/images/steps/6_small.png create mode 100644 spec/test_app/public/images/sxsw-ribbon-v1.png create mode 100644 spec/test_app/public/images/tab_bottom.gif create mode 100644 spec/test_app/public/images/tile-header.png create mode 100644 spec/test_app/public/images/tile-slider.png create mode 100644 spec/test_app/public/images/top-shine.png create mode 100644 spec/test_app/public/images/tree-nav-icons/bullet.gif create mode 100644 spec/test_app/public/images/tree-nav-icons/minus.gif create mode 100644 spec/test_app/public/images/tree-nav-icons/plus.gif create mode 100644 spec/test_app/public/images/tree-nav-icons/treeview-loading.gif create mode 100644 spec/test_app/public/images/tree-nav-icons/treeview-sprite.gif create mode 100644 spec/test_app/public/images/update.png create mode 100644 spec/test_app/public/images/visa_cid.gif create mode 100644 spec/test_app/public/images/wrapper-back-2.png create mode 100644 spec/test_app/public/images/wrapper-back.png create mode 100644 spec/test_app/public/images/yui-menubaritem_submenuindicator.png create mode 100644 spec/test_app/public/images/yui-menubaritem_submenuindicator_disabled.png create mode 100644 spec/test_app/public/images/yui-menuitem_checkbox.png create mode 100644 spec/test_app/public/images/yui-menuitem_checkbox_disabled.png create mode 100644 spec/test_app/public/images/yui-menuitem_submenuindicator.png create mode 100644 spec/test_app/public/images/yui-menuitem_submenuindicator_disabled.png create mode 100644 spec/test_app/public/images/yui-sprite.png create mode 100644 spec/test_app/public/javascripts/additional-methods.js create mode 100644 spec/test_app/public/javascripts/admin.js create mode 100644 spec/test_app/public/javascripts/admin/address_states.js create mode 100644 spec/test_app/public/javascripts/admin/checkouts/edit.js create mode 100644 spec/test_app/public/javascripts/admin/orders/edit.js create mode 100644 spec/test_app/public/javascripts/admin/orders/edit_form.js create mode 100644 spec/test_app/public/javascripts/admin/payments/new.js create mode 100644 spec/test_app/public/javascripts/admin/unobtrusive_handlers.js create mode 100644 spec/test_app/public/javascripts/application.js create mode 100644 spec/test_app/public/javascripts/calculator.js create mode 100644 spec/test_app/public/javascripts/checkout.js create mode 100644 spec/test_app/public/javascripts/datepicker.js create mode 100644 spec/test_app/public/javascripts/gateway.js create mode 100644 spec/test_app/public/javascripts/jquery-1.4.2.min.js create mode 100644 spec/test_app/public/javascripts/jquery-ui.js create mode 100755 spec/test_app/public/javascripts/jquery.alerts/images/help.gif create mode 100755 spec/test_app/public/javascripts/jquery.alerts/images/important.gif create mode 100755 spec/test_app/public/javascripts/jquery.alerts/images/info.gif create mode 100755 spec/test_app/public/javascripts/jquery.alerts/images/title.gif create mode 100755 spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.css create mode 100755 spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.js create mode 100644 spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.spree.css create mode 100644 spec/test_app/public/javascripts/jquery.autocomplete.min.js create mode 100644 spec/test_app/public/javascripts/jquery.js create mode 100644 spec/test_app/public/javascripts/jquery.suggest.js create mode 100644 spec/test_app/public/javascripts/jquery.template.js create mode 100644 spec/test_app/public/javascripts/jquery.tokeninput.js create mode 100644 spec/test_app/public/javascripts/jquery.validate.min.js create mode 100644 spec/test_app/public/javascripts/jrails.autocomplete.js create mode 100644 spec/test_app/public/javascripts/jrails.js create mode 100755 spec/test_app/public/javascripts/jsTree/jquery.tree.js create mode 100755 spec/test_app/public/javascripts/jsTree/plugins/jquery.tree.contextmenu.js create mode 100755 spec/test_app/public/javascripts/jsTree/themes/apple/bg.jpg create mode 100755 spec/test_app/public/javascripts/jsTree/themes/apple/dot_for_ie.gif create mode 100755 spec/test_app/public/javascripts/jsTree/themes/apple/icons.png create mode 100755 spec/test_app/public/javascripts/jsTree/themes/apple/style.css create mode 100755 spec/test_app/public/javascripts/jsTree/themes/apple/throbber.gif create mode 100644 spec/test_app/public/javascripts/lang/af.js create mode 100644 spec/test_app/public/javascripts/lang/ar.js create mode 100644 spec/test_app/public/javascripts/lang/de.js create mode 100644 spec/test_app/public/javascripts/lang/du.js create mode 100644 spec/test_app/public/javascripts/lang/en.js create mode 100644 spec/test_app/public/javascripts/lang/es.js create mode 100644 spec/test_app/public/javascripts/lang/fi.js create mode 100644 spec/test_app/public/javascripts/lang/fr.js create mode 100644 spec/test_app/public/javascripts/lang/gr.js create mode 100644 spec/test_app/public/javascripts/lang/he.js create mode 100644 spec/test_app/public/javascripts/lang/it.js create mode 100644 spec/test_app/public/javascripts/lang/nl.js create mode 100644 spec/test_app/public/javascripts/lang/no.js create mode 100644 spec/test_app/public/javascripts/lang/pt.js create mode 100644 spec/test_app/public/javascripts/lang/ro.js create mode 100644 spec/test_app/public/javascripts/lang/ru.js create mode 100644 spec/test_app/public/javascripts/lang/sp.js create mode 100644 spec/test_app/public/javascripts/lang/sv.js create mode 100644 spec/test_app/public/javascripts/lang/ua.js create mode 100644 spec/test_app/public/javascripts/localization/messages_cn.js create mode 100644 spec/test_app/public/javascripts/localization/messages_cs.js create mode 100644 spec/test_app/public/javascripts/localization/messages_da.js create mode 100644 spec/test_app/public/javascripts/localization/messages_de.js create mode 100644 spec/test_app/public/javascripts/localization/messages_es.js create mode 100644 spec/test_app/public/javascripts/localization/messages_fr.js create mode 100644 spec/test_app/public/javascripts/localization/messages_hu.js create mode 100644 spec/test_app/public/javascripts/localization/messages_it.js create mode 100644 spec/test_app/public/javascripts/localization/messages_kk.js create mode 100644 spec/test_app/public/javascripts/localization/messages_nl.js create mode 100644 spec/test_app/public/javascripts/localization/messages_no.js create mode 100644 spec/test_app/public/javascripts/localization/messages_pl.js create mode 100644 spec/test_app/public/javascripts/localization/messages_ptbr.js create mode 100644 spec/test_app/public/javascripts/localization/messages_ro.js create mode 100644 spec/test_app/public/javascripts/localization/messages_ru.js create mode 100644 spec/test_app/public/javascripts/localization/messages_se.js create mode 100644 spec/test_app/public/javascripts/localization/messages_sk.js create mode 100644 spec/test_app/public/javascripts/localization/messages_tr.js create mode 100644 spec/test_app/public/javascripts/localization/messages_tw.js create mode 100644 spec/test_app/public/javascripts/localization/messages_ua.js create mode 100644 spec/test_app/public/javascripts/nested-attribute.js create mode 100644 spec/test_app/public/javascripts/open_id.js create mode 100644 spec/test_app/public/javascripts/product.js create mode 100644 spec/test_app/public/javascripts/rails.js create mode 100644 spec/test_app/public/javascripts/taxonomy.js create mode 100644 spec/test_app/public/javascripts/zone.js create mode 100644 spec/test_app/public/robots.txt create mode 100755 spec/test_app/public/stylesheets/admin/admin-forms.css create mode 100644 spec/test_app/public/stylesheets/admin/admin-reset.css create mode 100644 spec/test_app/public/stylesheets/admin/admin-tables.css create mode 100755 spec/test_app/public/stylesheets/admin/admin-typography.css create mode 100644 spec/test_app/public/stylesheets/admin/admin.css create mode 100644 spec/test_app/public/stylesheets/admin/autocomplete.css create mode 100644 spec/test_app/public/stylesheets/admin/dashboard.css create mode 100644 spec/test_app/public/stylesheets/admin/edit_checkouts.css create mode 100644 spec/test_app/public/stylesheets/admin/grids.css create mode 100644 spec/test_app/public/stylesheets/admin/reset-fonts-grids-2-6-0.css create mode 100644 spec/test_app/public/stylesheets/admin/token-input.css create mode 100755 spec/test_app/public/stylesheets/admin/yui-includes.css create mode 100644 spec/test_app/public/stylesheets/datepicker.css create mode 100644 spec/test_app/public/stylesheets/jquery.autocomplete.css create mode 100644 spec/test_app/public/stylesheets/scaffold.css create mode 100644 spec/test_app/public/stylesheets/screen.css create mode 100755 spec/test_app/script/rails create mode 100644 spec/test_app/tmp/cache/588/EC0/Spree%3A%3AConfig create mode 100644 spree_faq.gemspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..5800638 --- /dev/null +++ b/LICENSE @@ -0,0 +1,23 @@ +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 Rails Dog LLC nor the names of its + 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/README.markdown b/README.md similarity index 64% rename from README.markdown rename to README.md index efa6b8e..37018ad 100644 --- a/README.markdown +++ b/README.md @@ -23,12 +23,5 @@ Editing FAQs =========== 1. Login to Administraton Console -2. Click on Configuration -3. Click on the Frequently Asked Questions link +2. Click on FAQ -Loading Sample FAQs -============= - -There are sample FAQs loaded as part of the rake db:bootstrap task. - -See the sample data in db/sample. diff --git a/Rakefile b/Rakefile index 3b41ccc..5659284 100644 --- a/Rakefile +++ b/Rakefile @@ -1,120 +1,66 @@ -# I think this is the one that should be moved to the extension Rakefile template - -# In rails 1.2, plugins aren't available in the path until they're loaded. -# Check to see if the rspec plugin is installed first and require -# it if it is. If not, use the gem version. - -# Determine where the RSpec plugin is by loading the boot -unless defined? SPREE_ROOT - ENV["RAILS_ENV"] = "test" - case - when ENV["SPREE_ENV_FILE"] - require File.dirname(ENV["SPREE_ENV_FILE"]) + "/boot" - when File.dirname(__FILE__) =~ %r{vendor/SPREE/vendor/extensions} - require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../")}/config/boot" - else - require "#{File.expand_path(File.dirname(__FILE__) + "/../../../")}/config/boot" - end -end - +require 'rubygems' require 'rake' -require 'rake/rdoctask' require 'rake/testtask' +require 'rake/packagetask' +require 'rake/gempackagetask' -rspec_base = File.expand_path(SPREE_ROOT + '/vendor/plugins/rspec/lib') -$LOAD_PATH.unshift(rspec_base) if File.exist?(rspec_base) -require 'spec/rake/spectask' -# require 'spec/translator' +spec = eval(File.read('spree_faq.gemspec')) -# Cleanup the SPREE_ROOT constant so specs will load the environment -Object.send(:remove_const, :SPREE_ROOT) +Rake::GemPackageTask.new(spec) do |p| + p.gem_spec = spec +end -extension_root = File.expand_path(File.dirname(__FILE__)) +desc "Release to gemcutter" +task :release => :package do + require 'rake/gemcutter' + Rake::Gemcutter::Tasks.new(spec).define + Rake::Task['gem:push'].invoke +end -task :default => :spec -task :stats => "spec:statsetup" +desc "Default Task" +task :default => [ :spec ] -desc "Run all specs in spec directory" -Spec::Rake::SpecTask.new(:spec) do |t| - t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""] - t.spec_files = FileList["#{extension_root}/spec/**/*_spec.rb"] -end +require 'rspec/core/rake_task' +RSpec::Core::RakeTask.new -namespace :spec do - desc "Run all specs in spec directory with RCov" - Spec::Rake::SpecTask.new(:rcov) do |t| - t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""] - t.spec_files = FileList['spec/**/*_spec.rb'] - t.rcov = true - t.rcov_opts = ['--exclude', 'spec', '--rails'] - end - - desc "Print Specdoc for all specs" - Spec::Rake::SpecTask.new(:doc) do |t| - t.spec_opts = ["--format", "specdoc", "--dry-run"] - t.spec_files = FileList['spec/**/*_spec.rb'] - end +# require 'cucumber/rake/task' +# Cucumber::Rake::Task.new do |t| +# t.cucumber_opts = %w{--format pretty} +# end - [:models, :controllers, :views, :helpers].each do |sub| - desc "Run the specs under spec/#{sub}" - Spec::Rake::SpecTask.new(sub) do |t| - t.spec_opts = ['--options', "\"#{extension_root}/spec/spec.opts\""] - t.spec_files = FileList["spec/#{sub}/**/*_spec.rb"] +desc "Regenerates a rails 3 app for testing" +task :test_app do + SPREE_PATH = ENV['SPREE_PATH'] + raise "SPREE_PATH should be specified" unless SPREE_PATH + require File.join(SPREE_PATH, 'lib/generators/spree/test_app_generator') + class AuthTestAppGenerator < Spree::Generators::TestAppGenerator + def tweak_gemfile + append_file 'Gemfile' do + <<-gems + gem 'spree_core', :path => '#{File.join(SPREE_PATH, 'core')}' + gem 'spree_auth', :path => '#{File.join(SPREE_PATH, 'auth')}' + gem 'spree_faq', :path => '../..' + gems + end end - end - - # Hopefully no one has written their extensions in pre-0.9 style - # desc "Translate specs from pre-0.9 to 0.9 style" - # task :translate do - # translator = ::Spec::Translator.new - # dir = RAILS_ROOT + '/spec' - # translator.translate(dir, dir) - # end - # Setup specs for stats - task :statsetup do - require 'code_statistics' - ::STATS_DIRECTORIES << %w(Model\ specs spec/models) - ::STATS_DIRECTORIES << %w(View\ specs spec/views) - ::STATS_DIRECTORIES << %w(Controller\ specs spec/controllers) - ::STATS_DIRECTORIES << %w(Helper\ specs spec/views) - ::CodeStatistics::TEST_TYPES << "Model specs" - ::CodeStatistics::TEST_TYPES << "View specs" - ::CodeStatistics::TEST_TYPES << "Controller specs" - ::CodeStatistics::TEST_TYPES << "Helper specs" - ::STATS_DIRECTORIES.delete_if {|a| a[0] =~ /test/} - end + def install_gems + system("cd spec/test_app && rake spree_core:install") + system("cd spec/test_app && rake spree_auth:install") + generate 'spree_faq:install' + end - namespace :db do - namespace :fixtures do - desc "Load fixtures (from spec/fixtures) into the current environment's database. Load specific fixtures using FIXTURES=x,y" - task :load => :environment do - require 'active_record/fixtures' - ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) - (ENV['FIXTURES'] ? ENV['FIXTURES'].split(/,/) : Dir.glob(File.join(RAILS_ROOT, 'spec', 'fixtures', '*.{yml,csv}'))).each do |fixture_file| - Fixtures.create_fixtures('spec/fixtures', File.basename(fixture_file, '.*')) - end - end + def migrate_db + run_migrations end end + AuthTestAppGenerator.start end -desc 'Generate documentation for the spree_faq extension.' -Rake::RDocTask.new(:rdoc) do |rdoc| - rdoc.rdoc_dir = 'rdoc' - rdoc.title = 'SpreeFaqExtension' - rdoc.options << '--line-numbers' << '--inline-source' - rdoc.rdoc_files.include('README') - rdoc.rdoc_files.include('lib/**/*.rb') -end - -# For extensions that are in transition -desc 'Test the spree_faq extension.' -Rake::TestTask.new(:test) do |t| - t.libs << 'lib' - t.pattern = 'test/**/*_test.rb' - t.verbose = true +namespace :test_app do + desc 'Rebuild test and cucumber databases' + task :rebuild_dbs do + system("cd spec/test_app && rake db:drop db:migrate RAILS_ENV=test") + end end -# Load any custom rakefiles for extension -Dir[File.dirname(__FILE__) + '/tasks/*.rake'].sort.each { |f| require f } \ No newline at end of file diff --git a/app/controllers/faqs_controller.rb b/app/controllers/faqs_controller.rb index 3ff0344..41b462f 100644 --- a/app/controllers/faqs_controller.rb +++ b/app/controllers/faqs_controller.rb @@ -5,10 +5,6 @@ def index @categories = QuestionCategory.all :include => :questions end - def show - @question = Question.find(params[:id]) - end - def default_title I18n.t 'frequently_asked_questions' end diff --git a/app/helpers/admin/question_categories_helper.rb b/app/helpers/admin/question_categories_helper.rb deleted file mode 100644 index 6e1d95d..0000000 --- a/app/helpers/admin/question_categories_helper.rb +++ /dev/null @@ -1,12 +0,0 @@ -module Admin::QuestionCategoriesHelper - def add_question_link(name) - link_to_function name do |page| - page << %{ - var new_question_id = "new_" + new Date().getTime(); - jQuery('#questions').append(new_question_html.replace(/new_\\d+/g, new_question_id)); - jQuery().scrollTo(jQuery('#questions .question:last'), 800); - } - end - end - -end diff --git a/app/helpers/faqs_helper.rb b/app/helpers/faqs_helper.rb deleted file mode 100644 index d36ed48..0000000 --- a/app/helpers/faqs_helper.rb +++ /dev/null @@ -1,2 +0,0 @@ -module FaqsHelper -end diff --git a/app/views/admin/question_categories/edit.html.erb b/app/views/admin/question_categories/edit.html.erb index 6d44754..e9aa143 100644 --- a/app/views/admin/question_categories/edit.html.erb +++ b/app/views/admin/question_categories/edit.html.erb @@ -2,13 +2,14 @@ <%= javascript_include_tag 'jquery.scrollTo-min' %> <%= stylesheet_link_tag 'spree_faq' %> <% end %> -<% form_for @question_category, :url => object_path do |f| %> - <% javascript_tag do %> +<%= form_for @question_category, :url => object_path do |f| %> + <%= render "shared/error_messages", :target => f.object %> + <%= javascript_tag do %> var new_question_html = '<%= generate_template(f, :questions) %>'; jQuery(document).ready(function($) { $('#new_question_link').click(function() { - $('#questions').append(new_question_html); + $('#questions').append(new_question_html.replace(/NEW_RECORD/g, $('#questions .question').size())); $('#questions .question:last .remove').click(function() { $(this).parent('.question').remove(); }); @@ -24,7 +25,7 @@
- <% f.field_container :name do %> + <%= f.field_container :name do %> <%= f.label :name, t("category_name") %> *
<%= f.text_field :name, :class => 'fullwidth title' %> <%= f.error_message_on :name %> @@ -34,12 +35,12 @@

Questions

<%= link_to_with_icon 'add', t('add_question'), '#', :id => 'new_question_link' %> - <% f.fields_for :questions do |question_form| %> + <%= f.fields_for :questions do |question_form| %> <%= render :partial => 'question', :locals => {:f => question_form } %> <% end %>
- <%= f.submit %> + <%= render :partial => 'admin/shared/edit_resource_links' %>
diff --git a/app/views/admin/question_categories/index.html.erb b/app/views/admin/question_categories/index.html.erb index 4411838..bed639e 100644 --- a/app/views/admin/question_categories/index.html.erb +++ b/app/views/admin/question_categories/index.html.erb @@ -1,32 +1,39 @@

-<%= image_tag "spinner.gif", :plugin=>"spree", :style => "display:none", :id => 'busy_indicator' %> -
+
-

Question Categories

+

<%= t("question_categories") %>

- + <%= hook :admin_question_categories_index_headers do %> + <% @question_categories.each do |category| %> - - - + + <%- locals = {:category => category} %> + <%= hook :admin_question_categories_index_rows, locals do %> + + + <% end %> <% end %> diff --git a/app/views/admin/question_categories/new.html.erb b/app/views/admin/question_categories/new.html.erb index ad694b8..3a2c586 100644 --- a/app/views/admin/question_categories/new.html.erb +++ b/app/views/admin/question_categories/new.html.erb @@ -1,11 +1,11 @@ -<%= error_messages_for :question_category %> -<% form_for @question_category, :url => collection_path do |f| %> +<%= form_for @question_category, :url => collection_path do |f| %> + <%= render "shared/error_messages", :target => f.object %>
- <% f.field_container :name do %> + <%= f.field_container :name do %> <%= f.label :name, t("name") %> *
<%= f.text_field :name, :class => 'fullwidth title' %> <%= f.error_message_on :name %> <% end %> - <%= f.submit t("create_category") %> + <%= render :partial => 'admin/shared/new_resource_links' %>
<% end %> diff --git a/app/views/faqs/index.html.erb b/app/views/faqs/index.html.erb index 5d28e58..49857da 100644 --- a/app/views/faqs/index.html.erb +++ b/app/views/faqs/index.html.erb @@ -2,12 +2,14 @@
<% @categories.each do |category| %> -
+

<%= h category.name %>

-
-<% content_for :head do %> - <% javascript_tag do %> - $(document).ready(function() { +<%= content_for :head do %> + <%= javascript_tag do %> + $(function() { $('.answer').hide(); $('.question').click(function() { var id = $(this).attr('id').split('_')[1]; diff --git a/autotest/discover.rb b/autotest/discover.rb new file mode 100644 index 0000000..f421dc5 --- /dev/null +++ b/autotest/discover.rb @@ -0,0 +1,2 @@ +Autotest.add_discovery { "rails" } +Autotest.add_discovery { "rspec2" } diff --git a/config/locales/en-GB.yml b/config/locales/en-GB.yml index c97212c..dfd6de3 100644 --- a/config/locales/en-GB.yml +++ b/config/locales/en-GB.yml @@ -1,7 +1,8 @@ --- en: frequently_asked_questions: Frequently Asked Questions - question_categoriess: Frequently Asked Questions + question_categories_admin: FAQ + question_categories: Frequently Asked Questions new_question_category: New Category questions: Questions create_category: Create Category diff --git a/config/locales/en-US.yml b/config/locales/en-US.yml index 968bcfc..57c92e4 100644 --- a/config/locales/en-US.yml +++ b/config/locales/en-US.yml @@ -1,6 +1,7 @@ --- en: frequently_asked_questions: Frequently Asked Questions + question_categories_admin: FAQ question_categories: Frequently Asked Questions new_question_category: New Category questions: Questions diff --git a/config/routes.rb b/config/routes.rb index ca02de6..195ba7a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,5 +1,7 @@ -map.resources :faq, :controller => 'faqs' +Rails.application.routes.draw do + match :faq, :to => 'faqs#index', :as => 'faq' -map.namespace :admin do |admin| - admin.resources :question_categories + namespace :admin do + resources :question_categories + end end diff --git a/db/sample/question_categories.yml b/db/sample/question_categories.yml deleted file mode 100644 index 48757b8..0000000 --- a/db/sample/question_categories.yml +++ /dev/null @@ -1,8 +0,0 @@ -sales: - name: Sales - -shipping: - name: Shipping - -billing: - name: Billing diff --git a/db/sample/questions.yml b/db/sample/questions.yml deleted file mode 100644 index f10ade2..0000000 --- a/db/sample/questions.yml +++ /dev/null @@ -1,39 +0,0 @@ -question_1: - question_category: sales - question: How much does it cost? - answer: Contact customer support - -question_2: - question_category: sales - question: Does it do X? - answer: Duh - -question_3: - question_category: sales - question: Can I return it? - answer: Maybe - -question_4: - question_category: shipping - question: How much does shipping cost? - answer: Contact customer support - -question_5: - question_category: shipping - question: What if it breaks? - answer: At your own risk - -question_6: - question_category: billing - question: Can I use VISA? - answer: Yes! - -question_7: - question_category: billing - question: Can I use PayPal? - answer: Yes! - -question_8: - question_category: billing - question: Can I use AMEX? - answer: Yes! diff --git a/faq_extension.rb b/faq_extension.rb deleted file mode 100644 index 4c648e3..0000000 --- a/faq_extension.rb +++ /dev/null @@ -1,20 +0,0 @@ -# Uncomment this if you reference any of your controllers in activate -# require_dependency 'application' - -class FaqExtension < Spree::Extension - version "1.0" - description "Describe your extension here" - url "http://yourwebsite.com/spree_faq" - - # Please use spree_faq/config/routes.rb instead for extension routes. - - # def self.require_gems(config) - # config.gem "gemname-goes-here", :version => '1.2.3' - # end - - def activate - end - -end - - diff --git a/faq_hooks.rb b/faq_hooks.rb deleted file mode 100644 index 4d6e877..0000000 --- a/faq_hooks.rb +++ /dev/null @@ -1,5 +0,0 @@ -class FaqHooks < Spree::ThemeSupport::HookListener - insert_after :admin_tabs do - %(<%= tab(:question_categories) %>) - end -end \ No newline at end of file diff --git a/lib/generators/spree_faq/install_generator.rb b/lib/generators/spree_faq/install_generator.rb new file mode 100644 index 0000000..8d47679 --- /dev/null +++ b/lib/generators/spree_faq/install_generator.rb @@ -0,0 +1,17 @@ +module SpreeFaq + module Generators + class InstallGenerator < Rails::Generators::Base + source_root File.expand_path("../../templates", __FILE__) + + desc "Configures your Rails application for use with spree_faq" + def copy_migrations + directory "db" + end + + def copy_public + directory "public" + end + + end + end +end diff --git a/db/migrate/20090526213535_create_questions.rb b/lib/generators/templates/db/migrate/20090526213535_create_questions.rb similarity index 100% rename from db/migrate/20090526213535_create_questions.rb rename to lib/generators/templates/db/migrate/20090526213535_create_questions.rb diff --git a/db/migrate/20090526213550_create_question_categories.rb b/lib/generators/templates/db/migrate/20090526213550_create_question_categories.rb similarity index 100% rename from db/migrate/20090526213550_create_question_categories.rb rename to lib/generators/templates/db/migrate/20090526213550_create_question_categories.rb diff --git a/public/javascripts/jquery.scrollTo-min.js b/lib/generators/templates/public/javascripts/jquery.scrollTo-min.js similarity index 100% rename from public/javascripts/jquery.scrollTo-min.js rename to lib/generators/templates/public/javascripts/jquery.scrollTo-min.js diff --git a/public/stylesheets/spree_faq.css b/lib/generators/templates/public/stylesheets/spree_faq.css similarity index 100% rename from public/stylesheets/spree_faq.css rename to lib/generators/templates/public/stylesheets/spree_faq.css diff --git a/lib/spree_faq.rb b/lib/spree_faq.rb new file mode 100644 index 0000000..2e308e0 --- /dev/null +++ b/lib/spree_faq.rb @@ -0,0 +1,3 @@ +require 'spree_core' +require 'spree_faq_hooks' +require 'spree_faq/engine' diff --git a/lib/spree_faq/engine.rb b/lib/spree_faq/engine.rb new file mode 100644 index 0000000..4d3eacd --- /dev/null +++ b/lib/spree_faq/engine.rb @@ -0,0 +1,12 @@ +require "spree_faq" + +module SpreeFaq + + class Engine < Rails::Engine + + def self.activate + end + + end + +end diff --git a/lib/spree_faq_hooks.rb b/lib/spree_faq_hooks.rb new file mode 100644 index 0000000..7c70ffc --- /dev/null +++ b/lib/spree_faq_hooks.rb @@ -0,0 +1,6 @@ +class SpreeFaqHooks < Spree::ThemeSupport::HookListener + insert_after :admin_tabs do + %(<%= tab(:question_categories, :label => :question_categories_admin) %>) + end +end + diff --git a/lib/tasks/faq_extension_tasks.rake b/lib/tasks/faq_extension_tasks.rake deleted file mode 100644 index dc59a7d..0000000 --- a/lib/tasks/faq_extension_tasks.rake +++ /dev/null @@ -1,30 +0,0 @@ -if Spree::Version::Major.to_i == 0 && Spree::Version::Minor.to_i < 9 && Spree::Version::Tiny.to_i <= 9 - namespace :db do - desc "Bootstrap your database for Spree." - task :bootstrap => :environment do - # load initial database fixtures (in db/sample/*.yml) into the current environment's database - ActiveRecord::Base.establish_connection(RAILS_ENV.to_sym) - Dir.glob(File.join(FaqExtension.root, "db", 'sample', '*.{yml,csv}')).each do |fixture_file| - Fixtures.create_fixtures("#{FaqExtension.root}/db/sample", File.basename(fixture_file, '.*')) - end - end - end -end - -namespace :spree do - namespace :extensions do - namespace :faq do - desc "Copies public assets of the Spree Faq to the instance public/ directory." - task :update => :environment do - is_svn_git_or_dir = proc {|path| path =~ /\.svn/ || path =~ /\.git/ || File.directory?(path) } - Dir[FaqExtension.root + "/public/**/*"].reject(&is_svn_git_or_dir).each do |file| - path = file.sub(FaqExtension.root, '') - directory = File.dirname(path) - puts "Copying #{path}..." - mkdir_p RAILS_ROOT + directory - cp file, RAILS_ROOT + path - end - end - end - end -end diff --git a/spec/controllers/faqs_controller_spec.rb b/spec/controllers/faqs_controller_spec.rb index a93f84b..5b2f967 100644 --- a/spec/controllers/faqs_controller_spec.rb +++ b/spec/controllers/faqs_controller_spec.rb @@ -11,13 +11,4 @@ response.should be_success end - it "should response to show" do - Question.should_receive(:find).with('1').and_return(:question) - - get :show, :id => 1 - - assigns(:question).should eql(:question) - response.should be_success - end - end diff --git a/spec/helpers/admin/question_categories_helper_spec.rb b/spec/helpers/admin/question_categories_helper_spec.rb deleted file mode 100644 index a1d21d7..0000000 --- a/spec/helpers/admin/question_categories_helper_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.dirname(__FILE__) + '/../../spec_helper' - -describe Admin::QuestionCategoriesHelper do - -end diff --git a/spec/helpers/faqs_helper_spec.rb b/spec/helpers/faqs_helper_spec.rb deleted file mode 100644 index 1d2dec9..0000000 --- a/spec/helpers/faqs_helper_spec.rb +++ /dev/null @@ -1,5 +0,0 @@ -require File.dirname(__FILE__) + '/../spec_helper' - -describe FaqsHelper do - -end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index ffde315..c82b72d 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -1,37 +1,28 @@ -unless defined? SPREE_ROOT - ENV["RAILS_ENV"] = "test" - case - when ENV["SPREE_ENV_FILE"] - require ENV["SPREE_ENV_FILE"] - when File.dirname(__FILE__) =~ %r{vendor/SPREE/vendor/extensions} - require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../../../")}/config/environment" - else - require "#{File.expand_path(File.dirname(__FILE__) + "/../../../../")}/config/environment" - end -end -require "#{SPREE_ROOT}/spec/spec_helper" +# This file is copied to ~/spec when you run 'ruby script/generate rspec' +# from the project root directory. +ENV["RAILS_ENV"] ||= 'test' +require File.expand_path("../test_app/config/environment", __FILE__) +require 'rspec/rails' -if File.directory?(File.dirname(__FILE__) + "/scenarios") - Scenario.load_paths.unshift File.dirname(__FILE__) + "/scenarios" -end -if File.directory?(File.dirname(__FILE__) + "/matchers") - Dir[File.dirname(__FILE__) + "/matchers/*.rb"].each {|file| require file } -end +# Requires supporting files with custom matchers and macros, etc, +# in ./support/ and its subdirectories. +Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f} -Spec::Runner.configure do |config| - # config.use_transactional_fixtures = true - # config.use_instantiated_fixtures = false - # config.fixture_path = RAILS_ROOT + '/spec/fixtures' - - # You can declare fixtures for each behaviour like this: - # describe "...." do - # fixtures :table_a, :table_b - # - # Alternatively, if you prefer to declare them only once, you can - # do so here, like so ... +RSpec.configure do |config| + # == Mock Framework # - # config.global_fixtures = :table_a, :table_b + # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line: # - # If you declare global fixtures, be aware that they will be declared - # for all of your examples, even those that don't use them. -end \ No newline at end of file + # config.mock_with :mocha + # config.mock_with :flexmock + # config.mock_with :rr + config.mock_with :rspec + + config.fixture_path = "#{::Rails.root}/spec/fixtures" + + # If you're not using ActiveRecord, or you'd prefer not to run each of your + # examples within a transaction, comment the following line or assign false + # instead of true. + config.use_transactional_fixtures = true +end + diff --git a/spec/test_app/Gemfile b/spec/test_app/Gemfile new file mode 100644 index 0000000..87b0d0b --- /dev/null +++ b/spec/test_app/Gemfile @@ -0,0 +1,19 @@ +source 'http://rubygems.org' + +gem 'rails', '~> 3.0.1' +gem 'sqlite3-ruby', :require => 'sqlite3' + +group :test do + gem 'rspec-rails', '~> 2.1.0' + gem 'fabrication' +end + +group :cucumber do + gem 'cucumber-rails', '~> 0.3.2' + gem 'database_cleaner', '~> 0.5.2' + gem 'capybara', '~> 0.3.9', :require => false +end + + gem 'spree_core', :path => '/home/josh/Playground/spree/core' + gem 'spree_auth', :path => '/home/josh/Playground/spree/auth' + gem 'spree_faq', :path => '../..' diff --git a/spec/test_app/Gemfile.lock b/spec/test_app/Gemfile.lock new file mode 100644 index 0000000..e99f2b7 --- /dev/null +++ b/spec/test_app/Gemfile.lock @@ -0,0 +1,188 @@ +PATH + remote: /home/josh/Playground/spree-faq + specs: + spree_faq (3.0.2) + spree_core (>= 0.30.1) + +PATH + remote: /home/josh/Playground/spree/auth + specs: + spree_auth (0.30.1) + authlogic (= 2.1.6) + cancan (>= 1.3.3) + spree_core (= 0.30.1) + +PATH + remote: /home/josh/Playground/spree/core + specs: + spree_core (0.30.1) + activemerchant (>= 1.7.1) + acts_as_list (>= 0.1.2) + faker (>= 0.3.1) + highline (>= 1.5.1) + jquery-rails (>= 0.2.2) + paperclip (>= 2.3.1.1) + rails (>= 3.0.1) + rd_awesome_nested_set (>= 1.4.4) + rd_resource_controller + rd_searchlogic (>= 3.0.0.rc3) + rd_unobtrusive_date_picker (>= 0.1.0) + state_machine (>= 0.9.4) + stringex (>= 1.0.3) + will_paginate (>= 3.0.pre) + +GEM + remote: http://rubygems.org/ + specs: + abstract (1.0.0) + actionmailer (3.0.1) + actionpack (= 3.0.1) + mail (~> 2.2.5) + actionpack (3.0.1) + activemodel (= 3.0.1) + activesupport (= 3.0.1) + builder (~> 2.1.2) + erubis (~> 2.6.6) + i18n (~> 0.4.1) + rack (~> 1.2.1) + rack-mount (~> 0.6.12) + rack-test (~> 0.5.4) + tzinfo (~> 0.3.23) + activemerchant (1.9.0) + activesupport (>= 2.3.2) + braintree (>= 2.0.0) + builder (>= 2.0.0) + activemodel (3.0.1) + activesupport (= 3.0.1) + builder (~> 2.1.2) + i18n (~> 0.4.1) + activerecord (3.0.1) + activemodel (= 3.0.1) + activesupport (= 3.0.1) + arel (~> 1.0.0) + tzinfo (~> 0.3.23) + activeresource (3.0.1) + activemodel (= 3.0.1) + activesupport (= 3.0.1) + activesupport (3.0.1) + acts_as_list (0.1.2) + arel (1.0.1) + activesupport (~> 3.0.0) + authlogic (2.1.6) + activesupport + braintree (2.6.2) + builder + builder (2.1.2) + cancan (1.4.1) + capybara (0.3.9) + culerity (>= 0.2.4) + mime-types (>= 1.16) + nokogiri (>= 1.3.3) + rack (>= 1.0.0) + rack-test (>= 0.5.4) + selenium-webdriver (>= 0.0.3) + childprocess (0.1.4) + ffi (~> 0.6.3) + cucumber (0.9.4) + builder (~> 2.1.2) + diff-lcs (~> 1.1.2) + gherkin (~> 2.2.9) + json (~> 1.4.6) + term-ansicolor (~> 1.0.5) + cucumber-rails (0.3.2) + cucumber (>= 0.8.0) + culerity (0.2.12) + database_cleaner (0.5.2) + diff-lcs (1.1.2) + erubis (2.6.6) + abstract (>= 1.0.0) + fabrication (0.9.1) + faker (0.3.1) + ffi (0.6.3) + rake (>= 0.8.7) + gherkin (2.2.9) + json (~> 1.4.6) + term-ansicolor (~> 1.0.5) + highline (1.6.1) + i18n (0.4.2) + jquery-rails (0.2.5) + rails (~> 3.0) + thor (~> 0.14.4) + json (1.4.6) + json_pure (1.4.6) + mail (2.2.10) + activesupport (>= 2.3.6) + i18n (~> 0.4.1) + mime-types (~> 1.16) + treetop (~> 1.4.8) + mime-types (1.16) + nokogiri (1.4.4) + paperclip (2.3.5) + activerecord + activesupport + polyglot (0.3.1) + rack (1.2.1) + rack-mount (0.6.13) + rack (>= 1.0.0) + rack-test (0.5.6) + rack (>= 1.0) + rails (3.0.1) + actionmailer (= 3.0.1) + actionpack (= 3.0.1) + activerecord (= 3.0.1) + activeresource (= 3.0.1) + activesupport (= 3.0.1) + bundler (~> 1.0.0) + railties (= 3.0.1) + railties (3.0.1) + actionpack (= 3.0.1) + activesupport (= 3.0.1) + rake (>= 0.8.4) + thor (~> 0.14.0) + rake (0.8.7) + rd_awesome_nested_set (1.4.4) + activerecord (>= 1.1) + rd_resource_controller (1.0.0) + rd_searchlogic (3.0.0.rc4) + activerecord (>= 3.0.0) + rd_unobtrusive_date_picker (0.1.0) + rspec (2.1.0) + rspec-core (~> 2.1.0) + rspec-expectations (~> 2.1.0) + rspec-mocks (~> 2.1.0) + rspec-core (2.1.0) + rspec-expectations (2.1.0) + diff-lcs (~> 1.1.2) + rspec-mocks (2.1.0) + rspec-rails (2.1.0) + rspec (~> 2.1.0) + rubyzip (0.9.4) + selenium-webdriver (0.1.0) + childprocess (= 0.1.4) + ffi (~> 0.6.3) + json_pure + rubyzip + sqlite3-ruby (1.3.2) + state_machine (0.9.4) + stringex (1.2.0) + term-ansicolor (1.0.5) + thor (0.14.6) + treetop (1.4.9) + polyglot (>= 0.3.1) + tzinfo (0.3.23) + will_paginate (3.0.pre2) + +PLATFORMS + ruby + +DEPENDENCIES + capybara (~> 0.3.9) + cucumber-rails (~> 0.3.2) + database_cleaner (~> 0.5.2) + fabrication + rails (~> 3.0.1) + rspec-rails (~> 2.1.0) + spree_auth! + spree_core! + spree_faq! + sqlite3-ruby diff --git a/spec/test_app/Rakefile b/spec/test_app/Rakefile new file mode 100644 index 0000000..685f6bc --- /dev/null +++ b/spec/test_app/Rakefile @@ -0,0 +1,7 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require File.expand_path('../config/application', __FILE__) +require 'rake' + +TestApp::Application.load_tasks diff --git a/spec/test_app/app/controllers/application_controller.rb b/spec/test_app/app/controllers/application_controller.rb new file mode 100644 index 0000000..e8065d9 --- /dev/null +++ b/spec/test_app/app/controllers/application_controller.rb @@ -0,0 +1,3 @@ +class ApplicationController < ActionController::Base + protect_from_forgery +end diff --git a/spec/test_app/app/helpers/application_helper.rb b/spec/test_app/app/helpers/application_helper.rb new file mode 100644 index 0000000..de6be79 --- /dev/null +++ b/spec/test_app/app/helpers/application_helper.rb @@ -0,0 +1,2 @@ +module ApplicationHelper +end diff --git a/spec/test_app/app/views/layouts/application.html.erb b/spec/test_app/app/views/layouts/application.html.erb new file mode 100644 index 0000000..92e4534 --- /dev/null +++ b/spec/test_app/app/views/layouts/application.html.erb @@ -0,0 +1,14 @@ + + + + TestApp + <%= stylesheet_link_tag :all %> + <%= javascript_include_tag :defaults %> + <%= csrf_meta_tag %> + + + +<%= yield %> + + + diff --git a/spec/test_app/config.ru b/spec/test_app/config.ru new file mode 100644 index 0000000..86a587d --- /dev/null +++ b/spec/test_app/config.ru @@ -0,0 +1,4 @@ +# This file is used by Rack-based servers to start the application. + +require ::File.expand_path('../config/environment', __FILE__) +run TestApp::Application diff --git a/spec/test_app/config/application.rb b/spec/test_app/config/application.rb new file mode 100644 index 0000000..a117d09 --- /dev/null +++ b/spec/test_app/config/application.rb @@ -0,0 +1,42 @@ +require File.expand_path('../boot', __FILE__) + +require 'rails/all' + +# If you have a Gemfile, require the gems listed there, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(:default, Rails.env) if defined?(Bundler) + +module TestApp + class Application < Rails::Application + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Custom directories with classes and modules you want to be autoloadable. + # config.autoload_paths += %W(#{config.root}/extras) + + # 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 ] + + # Activate observers that should always be running. + # config.active_record.observers = :cacher, :garbage_collector, :forum_observer + + # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. + # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. + # config.time_zone = 'Central Time (US & Canada)' + + # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. + # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] + # config.i18n.default_locale = :de + + # JavaScript files you want as :defaults (application.js is always included). + config.action_view.javascript_expansions[:defaults] = %w() + + # Configure the default encoding used in templates for Ruby 1.9. + config.encoding = "utf-8" + + # Configure sensitive parameters which will be filtered from the log file. + config.filter_parameters += [:password] + end +end diff --git a/spec/test_app/config/boot.rb b/spec/test_app/config/boot.rb new file mode 100644 index 0000000..ab6cb37 --- /dev/null +++ b/spec/test_app/config/boot.rb @@ -0,0 +1,13 @@ +require 'rubygems' + +# Set up gems listed in the Gemfile. +gemfile = File.expand_path('../../Gemfile', __FILE__) +begin + ENV['BUNDLE_GEMFILE'] = gemfile + require 'bundler' + Bundler.setup +rescue Bundler::GemNotFound => e + STDERR.puts e.message + STDERR.puts "Try running `bundle install`." + exit! +end if File.exist?(gemfile) diff --git a/spec/test_app/config/database.yml b/spec/test_app/config/database.yml new file mode 100644 index 0000000..4836b04 --- /dev/null +++ b/spec/test_app/config/database.yml @@ -0,0 +1,17 @@ +development: + adapter: sqlite3 + database: db/cucumber.sqlite3 + pool: 5 + timeout: 5000 + +test: + adapter: sqlite3 + database: db/test.sqlite3 + pool: 5 + timeout: 5000 + +cucumber: + adapter: sqlite3 + database: db/cucumber.sqlite3 + pool: 5 + timeout: 5000 diff --git a/spec/test_app/config/environment.rb b/spec/test_app/config/environment.rb new file mode 100644 index 0000000..f4cc1e4 --- /dev/null +++ b/spec/test_app/config/environment.rb @@ -0,0 +1,5 @@ +# Load the rails application +require File.expand_path('../application', __FILE__) + +# Initialize the rails application +TestApp::Application.initialize! diff --git a/spec/test_app/config/environments/cucumber.rb b/spec/test_app/config/environments/cucumber.rb new file mode 100644 index 0000000..132dc8d --- /dev/null +++ b/spec/test_app/config/environments/cucumber.rb @@ -0,0 +1,38 @@ +TestApp::Application.configure do + # Settings specified here will take precedence over those in config/environment.rb + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Use SQL instead of Active Record's schema dumper when creating the test database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + + # Print deprecation notices to the stderr + config.active_support.deprecation = :stderr + + config.action_mailer.default_url_options = { :host => 'testapp.com' } + +end diff --git a/spec/test_app/config/environments/development.rb b/spec/test_app/config/environments/development.rb new file mode 100644 index 0000000..1967636 --- /dev/null +++ b/spec/test_app/config/environments/development.rb @@ -0,0 +1,26 @@ +TestApp::Application.configure do + # Settings specified here will take precedence over those in config/environment.rb + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the webserver when you make code changes. + config.cache_classes = false + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_view.debug_rjs = true + config.action_controller.perform_caching = false + + # Don't care if the mailer can't send + config.action_mailer.raise_delivery_errors = false + + # Print deprecation notices to the Rails logger + config.active_support.deprecation = :log + + # Only use best-standards-support built into browsers + config.action_dispatch.best_standards_support = :builtin +end + diff --git a/spec/test_app/config/environments/production.rb b/spec/test_app/config/environments/production.rb new file mode 100644 index 0000000..dde1633 --- /dev/null +++ b/spec/test_app/config/environments/production.rb @@ -0,0 +1,49 @@ +TestApp::Application.configure do + # Settings specified here will take precedence over those in config/environment.rb + + # The production environment is meant for finished, "live" apps. + # Code is not reloaded between requests + config.cache_classes = true + + # Full error reports are disabled and caching is turned on + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Specifies the header that your server uses for sending files + config.action_dispatch.x_sendfile_header = "X-Sendfile" + + # For nginx: + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' + + # If you have no front-end server that supports something like X-Sendfile, + # just comment this out and Rails will serve the files + + # See everything in the log (default is :info) + # config.log_level = :debug + + # Use a different logger for distributed setups + # config.logger = SyslogLogger.new + + # Use a different cache store in production + # config.cache_store = :mem_cache_store + + # Disable Rails's static asset server + # In production, Apache or nginx will already do this + config.serve_static_assets = false + + # Enable serving of images, stylesheets, and javascripts from an asset server + # config.action_controller.asset_host = "http://assets.example.com" + + # Disable delivery errors, bad email addresses will be ignored + # config.action_mailer.raise_delivery_errors = false + + # Enable threaded mode + # config.threadsafe! + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation can not be found) + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners + config.active_support.deprecation = :notify +end diff --git a/spec/test_app/config/environments/test.rb b/spec/test_app/config/environments/test.rb new file mode 100644 index 0000000..1dafdec --- /dev/null +++ b/spec/test_app/config/environments/test.rb @@ -0,0 +1,62 @@ +TestApp::Application.configure do + # Settings specified here will take precedence over those in config/environment.rb + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Log error messages when you accidentally call methods on nil. + config.whiny_nils = true + + # Show full error reports and disable caching + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment + config.action_controller.allow_forgery_protection = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Use SQL instead of Active Record's schema dumper when creating the test database. + # This is necessary if your schema can't be completely dumped by the schema dumper, + # like if you have constraints or database-specific column types + # config.active_record.schema_format = :sql + + # Print deprecation notices to the stderr + config.active_support.deprecation = :stderr +end +CART = "cart" +ADDRESS = "address" +DELIVERY = "delivery" +PAYMENT = "payment" +CONFIRM = "confirm" +COMPLETE = "complete" +CANCELED = "canceled" +RETURNED = "returned" +RETURN_AUTHORIZED = "awaiting_return" + +ORDER_STATES = [CART, ADDRESS, DELIVERY, PAYMENT, CONFIRM, COMPLETE, CANCELED, RETURNED, RETURN_AUTHORIZED] + +READY = "ready" +SHIPPED = "shipped" +PARTIAL = "partial" +PENDING = "pending" +BACKORDER = "backorder" + +SHIPMENT_STATES = [READY, SHIPPED, PARTIAL, PENDING, BACKORDER] + +PROCESSING = 'processing' +FAILED = 'failed' +COMPLETED = 'completed' +VOID = 'void' +CHECKOUT = 'checkout' + +PAYMENT_STATES = [CHECKOUT, PROCESSING, FAILED, COMPLETED, VOID, PENDING] diff --git a/spec/test_app/config/initializers/backtrace_silencers.rb b/spec/test_app/config/initializers/backtrace_silencers.rb new file mode 100644 index 0000000..59385cd --- /dev/null +++ b/spec/test_app/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/spec/test_app/config/initializers/inflections.rb b/spec/test_app/config/initializers/inflections.rb new file mode 100644 index 0000000..9e8b013 --- /dev/null +++ b/spec/test_app/config/initializers/inflections.rb @@ -0,0 +1,10 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format +# (all these examples are active by default): +# ActiveSupport::Inflector.inflections do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end diff --git a/spec/test_app/config/initializers/mime_types.rb b/spec/test_app/config/initializers/mime_types.rb new file mode 100644 index 0000000..72aca7e --- /dev/null +++ b/spec/test_app/config/initializers/mime_types.rb @@ -0,0 +1,5 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf +# Mime::Type.register_alias "text/html", :iphone diff --git a/spec/test_app/config/initializers/secret_token.rb b/spec/test_app/config/initializers/secret_token.rb new file mode 100644 index 0000000..2acf5bb --- /dev/null +++ b/spec/test_app/config/initializers/secret_token.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key for verifying the integrity of signed cookies. +# 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. +TestApp::Application.config.secret_token = '4e01fa67d2f72ba99174c1fd23e054d380ba6daf59ee71d977aad664c94946d430045bfcfbb28ae615240ac75cfe808340603b201c13a0321744b78df66d830f' diff --git a/spec/test_app/config/initializers/session_store.rb b/spec/test_app/config/initializers/session_store.rb new file mode 100644 index 0000000..5a9809f --- /dev/null +++ b/spec/test_app/config/initializers/session_store.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +TestApp::Application.config.session_store :cookie_store, :key => '_test_app_session' + +# Use the database for sessions instead of the cookie-based default, +# which shouldn't be used to store highly confidential information +# (create the session table with "rake db:sessions:create") +# TestApp::Application.config.session_store :active_record_store diff --git a/spec/test_app/config/locales/en.yml b/spec/test_app/config/locales/en.yml new file mode 100644 index 0000000..a747bfa --- /dev/null +++ b/spec/test_app/config/locales/en.yml @@ -0,0 +1,5 @@ +# Sample localization file for English. Add more files in this directory for other locales. +# See http://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points. + +en: + hello: "Hello world" diff --git a/spec/test_app/config/routes.rb b/spec/test_app/config/routes.rb new file mode 100644 index 0000000..1c345fe --- /dev/null +++ b/spec/test_app/config/routes.rb @@ -0,0 +1,58 @@ +TestApp::Application.routes.draw do + # The priority is based upon order of creation: + # first created -> highest priority. + + # Sample of regular route: + # match 'products/:id' => 'catalog#view' + # Keep in mind you can assign values other than :controller and :action + + # Sample of named route: + # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase + # This route can be invoked with purchase_url(:id => product.id) + + # Sample resource route (maps HTTP verbs to controller actions automatically): + # resources :products + + # Sample resource route with options: + # resources :products do + # member do + # get 'short' + # post 'toggle' + # end + # + # collection do + # get 'sold' + # end + # end + + # Sample resource route with sub-resources: + # resources :products do + # resources :comments, :sales + # resource :seller + # end + + # Sample resource route with more complex sub-resources + # resources :products do + # resources :comments + # resources :sales do + # get 'recent', :on => :collection + # end + # end + + # Sample resource route within a namespace: + # namespace :admin do + # # Directs /admin/products/* to Admin::ProductsController + # # (app/controllers/admin/products_controller.rb) + # resources :products + # end + + # You can have the root of your site routed with "root" + # just remember to delete public/index.html. + # root :to => "welcome#index" + + # See how all your routes lay out with "rake routes" + + # This is a legacy wild controller route that's not recommended for RESTful applications. + # Note: This route will make all actions in every controller accessible via GET requests. + # match ':controller(/:action(/:id(.:format)))' +end diff --git a/spec/test_app/db/cucumber.sqlite3 b/spec/test_app/db/cucumber.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..c05a88c20d46ce7514984d81f06bfcfe4593f1b8 GIT binary patch literal 137216 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 true do |t| + t.string "firstname" + t.string "lastname" + t.string "address1" + t.string "address2" + t.string "city" + t.integer "state_id" + t.string "zipcode" + t.integer "country_id" + t.string "phone" + t.datetime "created_at" + t.datetime "updated_at" + t.string "state_name" + t.string "alternative_phone" + end + + create_table "adjustments", :force => true do |t| + t.integer "order_id" + t.string "type" + t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.string "description" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "adjustment_source_id" + t.string "adjustment_source_type" + t.string "secondary_type" + end + + create_table "assets", :force => true do |t| + t.integer "viewable_id" + t.string "viewable_type", :limit => 50 + t.string "attachment_content_type" + t.string "attachment_file_name" + t.integer "attachment_size" + t.integer "position" + t.string "type", :limit => 75 + t.datetime "attachment_updated_at" + t.integer "attachment_width" + t.integer "attachment_height" + end + + create_table "calculators", :force => true do |t| + t.string "type" + t.integer "calculable_id", :null => false + t.string "calculable_type", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "checkouts", :force => true do |t| + t.integer "order_id" + t.string "email" + t.string "ip_address" + t.text "special_instructions" + t.integer "bill_address_id" + t.datetime "completed_at" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "configurations", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "type", :limit => 50 + end + + add_index "configurations", ["name", "type"], :name => "index_configurations_on_name_and_type" + + create_table "countries", :force => true do |t| + t.string "iso_name" + t.string "iso" + t.string "name" + t.string "iso3" + t.integer "numcode" + end + + create_table "coupons", :force => true do |t| + t.string "code" + t.string "description" + t.integer "usage_limit" + t.boolean "combine" + t.datetime "expires_at" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "starts_at" + end + + create_table "creditcard_txns", :force => true do |t| + t.integer "creditcard_payment_id" + t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.integer "txn_type" + t.string "response_code" + t.text "avs_response" + t.text "cvv_response" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "creditcards", :force => true do |t| + t.text "number" + t.string "month" + t.string "year" + t.text "verification_value" + t.string "cc_type" + t.string "display_number" + t.string "first_name" + t.string "last_name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "start_month" + t.string "start_year" + t.string "issue_number" + t.integer "address_id" + t.integer "checkout_id" + end + + create_table "gateway_configurations", :force => true do |t| + t.integer "gateway_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateway_option_values", :force => true do |t| + t.integer "gateway_configuration_id" + t.integer "gateway_option_id" + t.text "value" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateway_options", :force => true do |t| + t.string "name" + t.text "description" + t.integer "gateway_id" + t.boolean "textarea", :default => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateways", :force => true do |t| + t.string "clazz" + t.string "name" + t.text "description" + t.boolean "active" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "inventory_units", :force => true do |t| + t.integer "variant_id" + t.integer "order_id" + t.string "state" + t.integer "lock_version", :default => 0 + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "line_items", :force => true do |t| + t.integer "order_id" + t.integer "variant_id" + t.integer "quantity", :null => false + t.decimal "price", :precision => 8, :scale => 2, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "line_items", ["order_id"], :name => "index_line_items_on_order_id" + add_index "line_items", ["variant_id"], :name => "index_line_items_on_variant_id" + + create_table "option_types", :force => true do |t| + t.string "name", :limit => 100 + t.string "presentation", :limit => 100 + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "option_types_prototypes", :id => false, :force => true do |t| + t.integer "prototype_id" + t.integer "option_type_id" + end + + create_table "option_values", :force => true do |t| + t.integer "option_type_id" + t.string "name" + t.integer "position" + t.string "presentation" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "option_values_variants", :id => false, :force => true do |t| + t.integer "variant_id" + t.integer "option_value_id" + end + + add_index "option_values_variants", ["variant_id"], :name => "index_option_values_variants_on_variant_id" + + create_table "orders", :force => true do |t| + t.integer "user_id" + t.string "number", :limit => 15 + t.decimal "item_total", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.decimal "total", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.datetime "created_at" + t.datetime "updated_at" + t.string "state" + t.string "token" + t.decimal "adjustment_total", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.decimal "credit_total", :precision => 8, :scale => 2, :default => 0.0, :null => false + end + + add_index "orders", ["number"], :name => "index_orders_on_number" + + create_table "payments", :force => true do |t| + t.integer "order_id" + t.datetime "created_at" + t.datetime "updated_at" + t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.integer "creditcard_id" + t.string "type" + end + + create_table "preferences", :force => true do |t| + t.string "attribute", :null => false, :limit => 100 + t.integer "owner_id", :null => false, :limit => 30 + t.string "owner_type", :null => false, :limit => 50 + t.integer "group_id" + t.string "group_type", :limit => 50 + t.string "value" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "preferences", ["owner_id", "owner_type", "attribute", "group_id", "group_type"], :name => "index_preferences_on_owner_and_attribute_and_preference", :unique => true + + create_table "product_option_types", :force => true do |t| + t.integer "product_id" + t.integer "option_type_id" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "product_properties", :force => true do |t| + t.integer "product_id" + t.integer "property_id" + t.string "value" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "products", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.datetime "created_at" + t.datetime "updated_at" + t.string "permalink" + t.datetime "available_on" + t.integer "tax_category_id" + t.integer "shipping_category_id" + t.datetime "deleted_at" + t.string "meta_description" + t.string "meta_keywords" + end + + add_index "products", ["available_on"], :name => "index_products_on_available_on" + add_index "products", ["deleted_at"], :name => "index_products_on_deleted_at" + add_index "products", ["name"], :name => "index_products_on_name" + add_index "products", ["permalink"], :name => "index_products_on_permalink" + + create_table "products_taxons", :id => false, :force => true do |t| + t.integer "product_id" + t.integer "taxon_id" + end + + add_index "products_taxons", ["product_id"], :name => "index_products_taxons_on_product_id" + add_index "products_taxons", ["taxon_id"], :name => "index_products_taxons_on_taxon_id" + + create_table "properties", :force => true do |t| + t.string "name" + t.string "presentation", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "properties_prototypes", :id => false, :force => true do |t| + t.integer "prototype_id" + t.integer "property_id" + end + + create_table "prototypes", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "roles", :force => true do |t| + t.string "name" + end + + create_table "roles_users", :id => false, :force => true do |t| + t.integer "role_id" + t.integer "user_id" + end + + add_index "roles_users", ["role_id"], :name => "index_roles_users_on_role_id" + add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id" + + create_table "shipments", :force => true do |t| + t.integer "order_id" + t.integer "shipping_method_id" + t.string "tracking" + t.datetime "created_at" + t.datetime "updated_at" + t.string "number" + t.decimal "cost", :precision => 8, :scale => 2 + t.datetime "shipped_at" + t.integer "address_id" + end + + create_table "shipping_categories", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "shipping_methods", :force => true do |t| + t.integer "zone_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "state_events", :force => true do |t| + t.integer "order_id" + t.integer "user_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "previous_state" + end + + create_table "states", :force => true do |t| + t.string "name" + t.string "abbr" + t.integer "country_id" + end + + create_table "tax_categories", :force => true do |t| + t.string "name" + t.string "description" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "tax_rates", :force => true do |t| + t.integer "zone_id" + t.decimal "amount", :precision => 8, :scale => 4 + t.datetime "created_at" + t.datetime "updated_at" + t.integer "tax_category_id" + end + + create_table "taxonomies", :force => true do |t| + t.string "name", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "taxons", :force => true do |t| + t.integer "taxonomy_id", :null => false + t.integer "parent_id" + t.integer "position", :default => 0 + t.string "name", :null => false + t.datetime "created_at" + t.datetime "updated_at" + t.string "permalink" + end + + create_table "users", :force => true do |t| + t.string "email" + t.string "crypted_password", :limit => 128, :default => "", :null => false + t.string "salt", :limit => 128, :default => "", :null => false + t.string "remember_token" + t.string "remember_token_expires_at" + t.datetime "created_at" + t.datetime "updated_at" + t.string "persistence_token" + t.string "single_access_token" + t.string "perishable_token" + t.integer "login_count", :default => 0, :null => false + t.integer "failed_login_count", :default => 0, :null => false + t.datetime "last_request_at" + t.datetime "current_login_at" + t.datetime "last_login_at" + t.string "current_login_ip" + t.string "last_login_ip" + t.string "login" + t.integer "ship_address_id" + t.integer "bill_address_id" + end + + create_table "variants", :force => true do |t| + t.integer "product_id" + t.string "sku", :default => "", :null => false + t.decimal "price", :precision => 8, :scale => 2, :null => false + t.decimal "weight", :precision => 8, :scale => 2 + t.decimal "height", :precision => 8, :scale => 2 + t.decimal "width", :precision => 8, :scale => 2 + t.decimal "depth", :precision => 8, :scale => 2 + t.datetime "deleted_at" + t.boolean "is_master", :default => false + end + + add_index "variants", ["product_id"], :name => "index_variants_on_product_id" + + create_table "zone_members", :force => true do |t| + t.integer "zone_id" + t.integer "zoneable_id" + t.string "zoneable_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "zones", :force => true do |t| + t.string "name" + t.string "description" + t.datetime "created_at" + t.datetime "updated_at" + end + end + + def self.down + # No going back + end +end diff --git a/spec/test_app/db/migrate/20090904192342_create_indexes_for_inventory_units.rb b/spec/test_app/db/migrate/20090904192342_create_indexes_for_inventory_units.rb new file mode 100644 index 0000000..801dba9 --- /dev/null +++ b/spec/test_app/db/migrate/20090904192342_create_indexes_for_inventory_units.rb @@ -0,0 +1,12 @@ +class CreateIndexesForInventoryUnits < ActiveRecord::Migration + def self.up + add_index(:inventory_units, :variant_id) + add_index(:inventory_units, :order_id) + end + + def self.down + remove_index(:inventory_units, :variant_id) + remove_index(:inventory_units, :order_id) + end +end + diff --git a/spec/test_app/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb b/spec/test_app/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb new file mode 100644 index 0000000..74ee903 --- /dev/null +++ b/spec/test_app/db/migrate/20090923100315_add_count_on_hand_to_variants_and_products.rb @@ -0,0 +1,36 @@ +class AddCountOnHandToVariantsAndProducts < ActiveRecord::Migration + def self.up + add_column :variants, :count_on_hand, :integer, :default => 0, :null => false + add_column :products, :count_on_hand, :integer, :default => 0, :null => false + + # In some cases needed to reflect changes in table structure + Variant.reset_column_information + Product.reset_column_information + + say_with_time 'Transfering inventory units with status on_hand to variants table...' do + Variant.all.each do |v| + v.update_attribute(:count_on_hand, v.inventory_units.with_state("on_hand").size) + InventoryUnit.destroy_all(:variant_id => v.id, :state => "on_hand") + end + end + + say_with_time 'Updating products count on hand' do + Product.all.each do |p| + product_count_on_hand = p.has_variants? ? + p.variants.inject(0) {|acc, v| acc + v.count_on_hand} : + (p.master ? p.master.count_on_hand : 0) + p.update_attribute(:count_on_hand, product_count_on_hand) + end + end + end + + def self.down + Variant.all.each do |v| + v.count_on_hand.times do + InventoryUnit.create(:variant => variant, :state => 'on_hand') + end + end + remove_column :variants, :count_on_hand + remove_column :products, :count_on_hand + end +end diff --git a/spec/test_app/db/migrate/20091007134354_change_taxons_to_nested_set.rb b/spec/test_app/db/migrate/20091007134354_change_taxons_to_nested_set.rb new file mode 100644 index 0000000..1cd72ba --- /dev/null +++ b/spec/test_app/db/migrate/20091007134354_change_taxons_to_nested_set.rb @@ -0,0 +1,40 @@ +class ChangeTaxonsToNestedSet < ActiveRecord::Migration + def self.up + add_column :taxons, :lft, :integer + add_column :taxons, :rgt, :integer + + Taxon.reset_column_information # So the new root ids get saved + + Taxon.class_eval do + # adapted from awesome nested set to use "position" information + indices = {} + + left_column_name = "lft" + right_column_name = "rgt" + quoted_parent_column_name = "parent_id" + scope = lambda{|node|} + + set_left_and_rights = lambda do |node| + # set left + node[left_column_name] = indices[scope.call(node)] += 1 + # find + find(:all, :conditions => ["#{quoted_parent_column_name} = ?", node], :order => "position ASC").each{|n| set_left_and_rights.call(n) } + # set right + node[right_column_name] = indices[scope.call(node)] += 1 + node.save! + end + + # Find root node(s) + find(:all, :conditions => "#{quoted_parent_column_name} IS NULL", :order => "position ASC").each do |root_node| + # setup index for this scope + indices[scope.call(root_node)] ||= 0 + set_left_and_rights.call(root_node) + end + end + end + + def self.down + remove_column :taxons, :lft + remove_column :taxons, :rgt + end +end diff --git a/spec/test_app/db/migrate/20091008091614_move_to_configurable_gateways.rb b/spec/test_app/db/migrate/20091008091614_move_to_configurable_gateways.rb new file mode 100644 index 0000000..046622b --- /dev/null +++ b/spec/test_app/db/migrate/20091008091614_move_to_configurable_gateways.rb @@ -0,0 +1,55 @@ +class MoveToConfigurableGateways < ActiveRecord::Migration + def self.up + drop_table :gateways + drop_table :gateway_options + drop_table :gateway_option_values + drop_table :gateway_configurations + + create_table :gateways, :force => true do |t| + t.string :type + t.string :name + t.text :description + t.boolean :active, :default => true + t.string :environment, :default => "development" + t.string :server, :default => "test" + t.boolean :test_mode, :default => true + t.timestamps + end + end + + def self.down + drop_table :gateways + create_table "gateway_configurations", :force => true do |t| + t.integer "gateway_id" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateway_option_values", :force => true do |t| + t.integer "gateway_configuration_id" + t.integer "gateway_option_id" + t.text "value" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateway_options", :force => true do |t| + t.string "name" + t.text "description" + t.integer "gateway_id" + t.boolean "textarea", :default => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "gateways", :force => true do |t| + t.string "clazz" + t.string "name" + t.text "description" + t.boolean "active" + t.datetime "created_at" + t.datetime "updated_at" + end + + end +end diff --git a/spec/test_app/db/migrate/20091012120519_product_groups_and_scopes.rb b/spec/test_app/db/migrate/20091012120519_product_groups_and_scopes.rb new file mode 100644 index 0000000..820a4c1 --- /dev/null +++ b/spec/test_app/db/migrate/20091012120519_product_groups_and_scopes.rb @@ -0,0 +1,25 @@ +class ProductGroupsAndScopes < ActiveRecord::Migration + def self.up + create_table(:product_groups) do |t| + t.column :name, :string + t.column :permalink, :string + t.column :order, :string + end + + create_table(:product_scopes) do |t| + t.column :product_group_id, :integer + t.column :name, :string + t.column :arguments, :text + end + + add_index :product_groups, :name + add_index :product_groups, :permalink + add_index :product_scopes, :name + add_index :product_scopes, :product_group_id + end + + def self.down + drop_table :product_groups + drop_table :product_scopes + end +end diff --git a/spec/test_app/db/migrate/20091015110842_add_open_id_authentication_tables.rb b/spec/test_app/db/migrate/20091015110842_add_open_id_authentication_tables.rb new file mode 100644 index 0000000..caae0d8 --- /dev/null +++ b/spec/test_app/db/migrate/20091015110842_add_open_id_authentication_tables.rb @@ -0,0 +1,20 @@ +class AddOpenIdAuthenticationTables < ActiveRecord::Migration + def self.up + create_table :open_id_authentication_associations, :force => true do |t| + t.integer :issued, :lifetime + t.string :handle, :assoc_type + t.binary :server_url, :secret + end + + create_table :open_id_authentication_nonces, :force => true do |t| + t.integer :timestamp, :null => false + t.string :server_url, :null => true + t.string :salt, :null => false + end + end + + def self.down + drop_table :open_id_authentication_associations + drop_table :open_id_authentication_nonces + end +end diff --git a/spec/test_app/db/migrate/20091015153048_add_openid_field_to_users.rb b/spec/test_app/db/migrate/20091015153048_add_openid_field_to_users.rb new file mode 100644 index 0000000..3c6b1fa --- /dev/null +++ b/spec/test_app/db/migrate/20091015153048_add_openid_field_to_users.rb @@ -0,0 +1,19 @@ + class AddOpenidFieldToUsers < ActiveRecord::Migration + def self.up + add_column :users, :openid_identifier, :string + add_index :users, :openid_identifier + + change_column :users, :login, :string, :default => nil, :null => true + change_column :users, :crypted_password, :string, :default => nil, :null => true + change_column :users, :salt, :string, :default => nil, :null => true + end + + def self.down + remove_column :users, :openid_identifier + + [:login, :crypted_password, :salt].each do |field| + User.all(:conditions => "#{field} is NULL").each { |user| user.update_attribute(field, "") if user.send(field).nil? } + change_column :users, field, :string, :default => "", :null => false + end + end + end diff --git a/spec/test_app/db/migrate/20091016174634_change_preference_value_type.rb b/spec/test_app/db/migrate/20091016174634_change_preference_value_type.rb new file mode 100644 index 0000000..8d64530 --- /dev/null +++ b/spec/test_app/db/migrate/20091016174634_change_preference_value_type.rb @@ -0,0 +1,10 @@ +class ChangePreferenceValueType < ActiveRecord::Migration + def self.up + remove_index :preferences, :name => 'index_preferences_on_owner_and_attribute_and_preference' + change_column :preferences, :value, :text + end + + def self.down + change_column :preferences, :value, :string + end +end diff --git a/spec/test_app/db/migrate/20091017175558_create_billing_integrations.rb b/spec/test_app/db/migrate/20091017175558_create_billing_integrations.rb new file mode 100644 index 0000000..aa2e17e --- /dev/null +++ b/spec/test_app/db/migrate/20091017175558_create_billing_integrations.rb @@ -0,0 +1,16 @@ +class CreateBillingIntegrations < ActiveRecord::Migration + def self.up + create_table :billing_integrations do |t| + t.string :type + t.string :name + t.text :description + t.boolean :active, :default => true + t.string :environment, :default => "development" + t.timestamps + end + end + + def self.down + drop_table :billing_integrations + end +end diff --git a/spec/test_app/db/migrate/20091021133257_charge_refactoring.rb b/spec/test_app/db/migrate/20091021133257_charge_refactoring.rb new file mode 100644 index 0000000..d36ddc6 --- /dev/null +++ b/spec/test_app/db/migrate/20091021133257_charge_refactoring.rb @@ -0,0 +1,35 @@ +class ChargeRefactoring < ActiveRecord::Migration + + class Checkout < ActiveRecord::Base + end + + # Hack to prevent issues with legacy migrations + class Order < ActiveRecord::Base + has_one :checkout + end + + def self.up + add_column :orders, :completed_at, :timestamp + Order.reset_column_information + Order.all.each {|o| o.update_attribute(:completed_at, o.checkout && o.checkout.read_attribute(:completed_at)) } + remove_column :checkouts, :completed_at + + change_column :adjustments, :amount, :decimal, :null => true, :default => nil, :precision => 8, :scale => 2 + Adjustment.update_all "type = secondary_type" + Adjustment.update_all "type = 'CouponCredit'", "type = 'Credit'" + remove_column :adjustments, :secondary_type + end + + def self.down + add_column :checkouts, :completed_at, :timestamp + Checkout.reset_column_information + Checkout.all.each{|c| c.update_attribute(:completed_at, c.order && c.order.completed_at)} + remove_column :orders, :completed_at + + add_column :adjustments, :secondary_type, :string + Adjustment.update_all "secondary_type = type" + Adjustment.update_all "type = 'Charge'", "type like '%Charge'" + Adjustment.update_all "type = 'Credit'", "type like '%Credit'" + change_column :adjustments, :amount, :decimal, :null => false, :default => 0, :precision => 8, :scale => 2 + end +end diff --git a/spec/test_app/db/migrate/20091104151730_add_some_indexes.rb b/spec/test_app/db/migrate/20091104151730_add_some_indexes.rb new file mode 100644 index 0000000..e9cbb5d --- /dev/null +++ b/spec/test_app/db/migrate/20091104151730_add_some_indexes.rb @@ -0,0 +1,21 @@ +class AddSomeIndexes < ActiveRecord::Migration + def self.up + add_index(:taxons, :permalink) + add_index(:taxons, :parent_id) + add_index(:taxons, :taxonomy_id) + add_index(:assets, :viewable_id) + add_index(:assets, [:viewable_type, :type]) + add_index(:product_properties, :product_id) + add_index(:option_values_variants, [:variant_id, :option_value_id]) + end + + def self.down + remove_index(:taxons, :permalink) + remove_index(:taxons, :parent_id) + remove_index(:taxons, :taxonomy_id) + remove_index(:assets, :viewable_id) + remove_index(:assets, [:viewable_type, :type]) + remove_index(:product_properties, :product_id) + remove_index(:option_values_variants, [:variant_id, :option_value_id]) + end +end diff --git a/spec/test_app/db/migrate/20091126190904_checkout_state_machine.rb b/spec/test_app/db/migrate/20091126190904_checkout_state_machine.rb new file mode 100644 index 0000000..5e6b484 --- /dev/null +++ b/spec/test_app/db/migrate/20091126190904_checkout_state_machine.rb @@ -0,0 +1,13 @@ +class CheckoutStateMachine < ActiveRecord::Migration + def self.up + change_table :checkouts do |t| + t.string :state + end + end + + def self.down + change_table :checkouts do |t| + t.remove :state + end + end +end diff --git a/spec/test_app/db/migrate/20091209153045_state_for_shipments.rb b/spec/test_app/db/migrate/20091209153045_state_for_shipments.rb new file mode 100644 index 0000000..3094333 --- /dev/null +++ b/spec/test_app/db/migrate/20091209153045_state_for_shipments.rb @@ -0,0 +1,9 @@ +class StateForShipments < ActiveRecord::Migration + def self.up + add_column "shipments", "state", :string + end + + def self.down + remove_column "shipments", "state" + end +end diff --git a/spec/test_app/db/migrate/20091209202200_make_state_events_polymorphic.rb b/spec/test_app/db/migrate/20091209202200_make_state_events_polymorphic.rb new file mode 100644 index 0000000..8224d47 --- /dev/null +++ b/spec/test_app/db/migrate/20091209202200_make_state_events_polymorphic.rb @@ -0,0 +1,12 @@ +class MakeStateEventsPolymorphic < ActiveRecord::Migration + def self.up + rename_column :state_events, :order_id, :stateful_id + add_column :state_events, :stateful_type, :string + StateEvent.update_all(:stateful_type => 'Order') + end + + def self.down + rename_column :state_events, :stateful_id, :order_id + remove_column :state_events, :stateful_type + end +end diff --git a/spec/test_app/db/migrate/20091211203813_ship_address_id_for_checkouts.rb b/spec/test_app/db/migrate/20091211203813_ship_address_id_for_checkouts.rb new file mode 100644 index 0000000..cb4cf03 --- /dev/null +++ b/spec/test_app/db/migrate/20091211203813_ship_address_id_for_checkouts.rb @@ -0,0 +1,9 @@ +class ShipAddressIdForCheckouts < ActiveRecord::Migration + def self.up + add_column "checkouts", "ship_address_id", :integer + end + + def self.down + remove_column "checkouts", "ship_address_id" + end +end diff --git a/spec/test_app/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb b/spec/test_app/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb new file mode 100644 index 0000000..e7c86cd --- /dev/null +++ b/spec/test_app/db/migrate/20091212161118_shipping_method_id_for_checkouts.rb @@ -0,0 +1,9 @@ +class ShippingMethodIdForCheckouts < ActiveRecord::Migration + def self.up + add_column "checkouts", "shipping_method_id", :integer + end + + def self.down + remove_column "checkouts", "shipping_method_id" + end +end diff --git a/spec/test_app/db/migrate/20091213222815_creditcard_last_four_digits.rb b/spec/test_app/db/migrate/20091213222815_creditcard_last_four_digits.rb new file mode 100644 index 0000000..fafa791 --- /dev/null +++ b/spec/test_app/db/migrate/20091213222815_creditcard_last_four_digits.rb @@ -0,0 +1,19 @@ +class CreditcardLastFourDigits < ActiveRecord::Migration + + # Hack to allow for legacy migrations + class Creditcard < ActiveRecord::Base + end + + def self.up + rename_column :creditcards, :display_number, :last_digits + + Creditcard.reset_column_information + Creditcard.all.each do |card| + card.update_attribute(:last_digits, card.last_digits.gsub("XXXX-XXXX-XXXX-", "")) if card.last_digits.present? + end + end + + def self.down + rename_column :creditcards, :last_digits, :display_number + end +end diff --git a/spec/test_app/db/migrate/20091214183826_populate_legacy_shipment_state.rb b/spec/test_app/db/migrate/20091214183826_populate_legacy_shipment_state.rb new file mode 100644 index 0000000..810e3c4 --- /dev/null +++ b/spec/test_app/db/migrate/20091214183826_populate_legacy_shipment_state.rb @@ -0,0 +1,19 @@ +class PopulateLegacyShipmentState < ActiveRecord::Migration + # Hack to allow for legacy migrations + class Shipment < ActiveRecord::Base + end + + def self.up + Shipment.all.each do |shipment| + if shipment.shipped_at + shipment.state = "shipped" + else + shipment.state = "pending" + end + shipment.save + end + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20100105090147_add_cost_price.rb b/spec/test_app/db/migrate/20100105090147_add_cost_price.rb new file mode 100644 index 0000000..6f3aa13 --- /dev/null +++ b/spec/test_app/db/migrate/20100105090147_add_cost_price.rb @@ -0,0 +1,9 @@ +class AddCostPrice < ActiveRecord::Migration + def self.up + add_column :variants, :cost_price, :decimal, :null => true, :default => nil, :precision => 8, :scale => 2 + end + + def self.down + remove_column :variants, :cost_price + end +end diff --git a/spec/test_app/db/migrate/20100105132138_shipment_id_for_inventory_units.rb b/spec/test_app/db/migrate/20100105132138_shipment_id_for_inventory_units.rb new file mode 100644 index 0000000..fa104ab --- /dev/null +++ b/spec/test_app/db/migrate/20100105132138_shipment_id_for_inventory_units.rb @@ -0,0 +1,21 @@ +class ShipmentIdForInventoryUnits < ActiveRecord::Migration + def self.up + add_column "inventory_units", "shipment_id", :integer + add_index(:inventory_units, :shipment_id) + + # migrate legacy shipments + Shipment.all.each do |shipment| + unless shipment.order + puts "Warning: shipment has invalid order - #{shipment.id}" + next + end + shipment.order.inventory_units.each do |unit| + unit.update_attribute("shipment_id", shipment.id) + end + end + end + + def self.down + remove_column "inventory_units", "shipment_id" + end +end diff --git a/spec/test_app/db/migrate/20100111205525_cim_fields_for_creditcards.rb b/spec/test_app/db/migrate/20100111205525_cim_fields_for_creditcards.rb new file mode 100644 index 0000000..a30ddf3 --- /dev/null +++ b/spec/test_app/db/migrate/20100111205525_cim_fields_for_creditcards.rb @@ -0,0 +1,11 @@ +class CimFieldsForCreditcards < ActiveRecord::Migration + def self.up + add_column "creditcards", "gateway_customer_profile_id", :string + add_column "creditcards", "gateway_payment_profile_id", :string + end + + def self.down + remove_column "creditcards", "gateway_customer_profile_id" + remove_column "creditcards", "gateway_payment_profile_id" + end +end diff --git a/spec/test_app/db/migrate/20100112151511_create_return_authorizations.rb b/spec/test_app/db/migrate/20100112151511_create_return_authorizations.rb new file mode 100644 index 0000000..70c6d3b --- /dev/null +++ b/spec/test_app/db/migrate/20100112151511_create_return_authorizations.rb @@ -0,0 +1,16 @@ +class CreateReturnAuthorizations < ActiveRecord::Migration + def self.up + create_table :return_authorizations do |t| + t.string :number + t.decimal :amount, :precision => 8, :scale => 2, :default => 0.0, :null => false + t.references :order + t.text :reason + t.string :state + t.timestamps + end + end + + def self.down + drop_table :return_authorizations + end +end diff --git a/spec/test_app/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb b/spec/test_app/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb new file mode 100644 index 0000000..00e7d5f --- /dev/null +++ b/spec/test_app/db/migrate/20100113090919_add_return_authorization_to_inventory_units.rb @@ -0,0 +1,9 @@ +class AddReturnAuthorizationToInventoryUnits < ActiveRecord::Migration + def self.up + add_column :inventory_units, :return_authorization_id, :integer + end + + def self.down + remove_column :inventory_units, :return_authorization_id + end +end diff --git a/spec/test_app/db/migrate/20100113203104_create_trackers.rb b/spec/test_app/db/migrate/20100113203104_create_trackers.rb new file mode 100644 index 0000000..6078395 --- /dev/null +++ b/spec/test_app/db/migrate/20100113203104_create_trackers.rb @@ -0,0 +1,14 @@ +class CreateTrackers < ActiveRecord::Migration + def self.up + create_table :trackers do |t| + t.string :environment + t.string :analytics_id + t.boolean :active, :default => true + t.timestamps + end + end + + def self.down + drop_table :trackers + end +end diff --git a/spec/test_app/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb b/spec/test_app/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb new file mode 100644 index 0000000..d2bbac9 --- /dev/null +++ b/spec/test_app/db/migrate/20100121160010_creditcard_id_for_creditcard_txns.rb @@ -0,0 +1,9 @@ +class CreditcardIdForCreditcardTxns < ActiveRecord::Migration + def self.up + add_column "creditcard_txns", "creditcard_id", :integer + end + + def self.down + remove_column "creditcard_txns", "creditcard_id" + end +end diff --git a/spec/test_app/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb b/spec/test_app/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb new file mode 100644 index 0000000..98ef6a9 --- /dev/null +++ b/spec/test_app/db/migrate/20100121183934_original_creditcard_txn_id_for_creditcard_txns.rb @@ -0,0 +1,9 @@ +class OriginalCreditcardTxnIdForCreditcardTxns < ActiveRecord::Migration + def self.up + add_column "creditcard_txns", "original_creditcard_txn_id", :integer + end + + def self.down + remove_column "creditcard_txns", "original_creditcard_txn_id" + end +end diff --git a/spec/test_app/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb b/spec/test_app/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb new file mode 100644 index 0000000..4dccff2 --- /dev/null +++ b/spec/test_app/db/migrate/20100125145351_add_test_mode_to_billing_integration.rb @@ -0,0 +1,11 @@ +class AddTestModeToBillingIntegration < ActiveRecord::Migration + def self.up + add_column :billing_integrations, :test_mode, :boolean, :default => true + add_column :billing_integrations, :server, :string, :default => "test" + end + + def self.down + remove_column :billing_integrations, :test_mode + remove_column :billing_integrations, :server + end +end diff --git a/spec/test_app/db/migrate/20100126103714_create_products_product_groups.rb b/spec/test_app/db/migrate/20100126103714_create_products_product_groups.rb new file mode 100644 index 0000000..0317884 --- /dev/null +++ b/spec/test_app/db/migrate/20100126103714_create_products_product_groups.rb @@ -0,0 +1,12 @@ +class CreateProductsProductGroups < ActiveRecord::Migration + def self.up + create_table :product_groups_products, :id => false do |t| + t.references :product + t.references :product_group + end + end +#product_group_memberships + def self.down + drop_table :product_groups_products + end +end diff --git a/spec/test_app/db/migrate/20100209025806_create_payment_methods.rb b/spec/test_app/db/migrate/20100209025806_create_payment_methods.rb new file mode 100644 index 0000000..722f04d --- /dev/null +++ b/spec/test_app/db/migrate/20100209025806_create_payment_methods.rb @@ -0,0 +1,20 @@ +class CreatePaymentMethods < ActiveRecord::Migration + def self.up + create_table :payment_methods do |t| + t.string :type + t.string :name + t.text :description + t.boolean :active, :default => true + t.string :environment, :default => "development" + t.timestamps + end + # TODO - also migrate any legacy configurations for gateways and billing integrations before dropping the old tables + # we probably also need to do this inside the payment_gateway extension b/c table won't exist yet in fresh bootstrap + #drop_table :billing_integrations + #drop_table :gateways + end + + def self.down + drop_table :payment_methods + end +end diff --git a/spec/test_app/db/migrate/20100209144531_polymorphic_payments.rb b/spec/test_app/db/migrate/20100209144531_polymorphic_payments.rb new file mode 100644 index 0000000..7004d6f --- /dev/null +++ b/spec/test_app/db/migrate/20100209144531_polymorphic_payments.rb @@ -0,0 +1,29 @@ +class PolymorphicPayments < ActiveRecord::Migration + def self.up + remove_column :payments, :type + remove_column :payments, :creditcard_id + rename_column :payments, :order_id, :payable_id + change_table :payments do |t| + t.string :payable_type + t.string :payment_method + t.references :source, :polymorphic => true + end + execute "UPDATE payments SET payable_type = 'Order'" + + Creditcard.all.each do |creditcard| + if checkout = Checkout.find_by_id(creditcard.checkout_id) and checkout.order + if payment = checkout.order.payments.first + execute "UPDATE payments SET source_type = 'Creditcard', source_id = #{creditcard.id} WHERE id = #{payment.id}" + end + end + end + + change_table :creditcards do |t| + t.remove :checkout_id + end + end + + def self.down + # no going back! + end +end diff --git a/spec/test_app/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb b/spec/test_app/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb new file mode 100644 index 0000000..e4cc41c --- /dev/null +++ b/spec/test_app/db/migrate/20100213103131_change_payments_payment_method_to_belongs_to.rb @@ -0,0 +1,11 @@ +class ChangePaymentsPaymentMethodToBelongsTo < ActiveRecord::Migration + def self.up + remove_column "payments", "payment_method" + add_column "payments", "payment_method_id", :integer + end + + def self.down + add_column "payments", "payment_method", :string + remove_column "payments", "payment_method_id" + end +end diff --git a/spec/test_app/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb b/spec/test_app/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb new file mode 100644 index 0000000..bcca85f --- /dev/null +++ b/spec/test_app/db/migrate/20100214212536_assign_creditcard_txns_to_payment.rb @@ -0,0 +1,16 @@ +class AssignCreditcardTxnsToPayment < ActiveRecord::Migration + def self.up + add_column "creditcard_txns", "payment_id", :integer + ActiveRecord::Base.connection.select_all("SELECT * FROM creditcard_txns").each do |txn_attrs| + if creditcard = Creditcard.find_by_id(txn_attrs["creditcard_id"]) and creditcard.payments.first + execute "UPDATE creditcard_txns SET payment_id = #{creditcard.payments.first.id} WHERE id = #{txn_attrs['id']}" + end + end + remove_column "creditcard_txns", "creditcard_payment_id" + end + + def self.down + remove_column "creditcard_txns", "payment_id" + add_column "creditcard_txns", "creditcard_payment_id", :integer + end +end diff --git a/spec/test_app/db/migrate/20100223170312_sti_for_transactions.rb b/spec/test_app/db/migrate/20100223170312_sti_for_transactions.rb new file mode 100644 index 0000000..031027e --- /dev/null +++ b/spec/test_app/db/migrate/20100223170312_sti_for_transactions.rb @@ -0,0 +1,14 @@ +class StiForTransactions < ActiveRecord::Migration + def self.up + rename_table "creditcard_txns", "transactions" + add_column "transactions", "type", :string + remove_column "transactions", "creditcard_id" + Transaction.update_all(:type => 'CreditcardTxn') if defined? Transaction + end + + def self.down + rename_table "transactions", "creditcard_txns" + remove_column "transactions", "type" + add_column "transactions", "creditcard_id", :integer + end +end diff --git a/spec/test_app/db/migrate/20100223183812_drop_billing_integrations.rb b/spec/test_app/db/migrate/20100223183812_drop_billing_integrations.rb new file mode 100644 index 0000000..60c6dcb --- /dev/null +++ b/spec/test_app/db/migrate/20100223183812_drop_billing_integrations.rb @@ -0,0 +1,16 @@ +class DropBillingIntegrations < ActiveRecord::Migration + def self.up + drop_table :billing_integrations + end + + def self.down + create_table :billing_integrations do |t| + t.string :type + t.string :name + t.text :description + t.boolean :active, :default => true + t.string :environment, :default => "development" + t.timestamps + end + end +end diff --git a/spec/test_app/db/migrate/20100224153127_deleted_at_for_payment_methods.rb b/spec/test_app/db/migrate/20100224153127_deleted_at_for_payment_methods.rb new file mode 100644 index 0000000..168f17a --- /dev/null +++ b/spec/test_app/db/migrate/20100224153127_deleted_at_for_payment_methods.rb @@ -0,0 +1,13 @@ +class DeletedAtForPaymentMethods < ActiveRecord::Migration + def self.up + change_table :payment_methods do |t| + t.timestamp :deleted_at, :default => nil + end + end + + def self.down + change_table :payment_methods do |t| + t.remove :deleted_at + end + end +end diff --git a/spec/test_app/db/migrate/20100301163454_add_adjustments_index.rb b/spec/test_app/db/migrate/20100301163454_add_adjustments_index.rb new file mode 100644 index 0000000..fecc5cd --- /dev/null +++ b/spec/test_app/db/migrate/20100301163454_add_adjustments_index.rb @@ -0,0 +1,10 @@ +class AddAdjustmentsIndex < ActiveRecord::Migration + def self.up + add_index(:adjustments, :order_id) + end + + def self.down + remove_index(:adjustments, :order_id) + end +end + diff --git a/spec/test_app/db/migrate/20100306153445_fix_by_popularity.rb b/spec/test_app/db/migrate/20100306153445_fix_by_popularity.rb new file mode 100644 index 0000000..2426a8a --- /dev/null +++ b/spec/test_app/db/migrate/20100306153445_fix_by_popularity.rb @@ -0,0 +1,8 @@ +class FixByPopularity < ActiveRecord::Migration + def self.up + ProductScope.update_all("name='descend_by_popularity'", "name='by_popularity'") + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20100317120946_add_alt_text_to_images.rb b/spec/test_app/db/migrate/20100317120946_add_alt_text_to_images.rb new file mode 100644 index 0000000..8d60703 --- /dev/null +++ b/spec/test_app/db/migrate/20100317120946_add_alt_text_to_images.rb @@ -0,0 +1,9 @@ +class AddAltTextToImages < ActiveRecord::Migration + def self.up + add_column :assets, :alt, :text + end + + def self.down + remove_column :assets, :alt + end +end diff --git a/spec/test_app/db/migrate/20100427121301_add_display_to_payment_methods.rb b/spec/test_app/db/migrate/20100427121301_add_display_to_payment_methods.rb new file mode 100644 index 0000000..2683f32 --- /dev/null +++ b/spec/test_app/db/migrate/20100427121301_add_display_to_payment_methods.rb @@ -0,0 +1,9 @@ +class AddDisplayToPaymentMethods < ActiveRecord::Migration + def self.up + add_column :payment_methods, :display, :string, :default => nil + end + + def self.down + remove_column :payment_methods, :display + end +end diff --git a/spec/test_app/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb b/spec/test_app/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb new file mode 100755 index 0000000..34c249e --- /dev/null +++ b/spec/test_app/db/migrate/20100504142133_add_addresses_checkouts_indexes.rb @@ -0,0 +1,16 @@ +class AddAddressesCheckoutsIndexes < ActiveRecord::Migration + def self.up + add_index :addresses, :firstname + add_index :addresses, :lastname + add_index :checkouts, :order_id + add_index :checkouts, :bill_address_id + end + + def self.down + remove_index :checkouts, :bill_address_id + remove_index :checkouts, :order_id + remove_index :addresses, :lastname + remove_index :addresses, :firstname + end +end + diff --git a/spec/test_app/db/migrate/20100506180619_add_icon_to_taxons.rb b/spec/test_app/db/migrate/20100506180619_add_icon_to_taxons.rb new file mode 100644 index 0000000..add1fa5 --- /dev/null +++ b/spec/test_app/db/migrate/20100506180619_add_icon_to_taxons.rb @@ -0,0 +1,18 @@ +class AddIconToTaxons < ActiveRecord::Migration + def self.up + # skip this migration if the attribute already exists because of advanced taxon extension + return if Taxon.new.respond_to? :icon_file_name + add_column :taxons, :icon_file_name, :string + add_column :taxons, :icon_content_type, :string + add_column :taxons, :icon_file_size, :integer + add_column :taxons, :icon_updated_at, :datetime + end + + def self.down + remove_column :taxons, :icon_file_name + remove_column :taxons, :icon_content_type + remove_column :taxons, :icon_file_size + remove_column :taxons, :icon_updated_at + end + +end diff --git a/spec/test_app/db/migrate/20100506185838_add_description_to_taxons.rb b/spec/test_app/db/migrate/20100506185838_add_description_to_taxons.rb new file mode 100644 index 0000000..9a047bd --- /dev/null +++ b/spec/test_app/db/migrate/20100506185838_add_description_to_taxons.rb @@ -0,0 +1,11 @@ +class AddDescriptionToTaxons < ActiveRecord::Migration + def self.up + # skip this migration if the attribute already exists because of advanced taxon extension + return if Taxon.new.respond_to? :description + add_column :taxons, :description, :text + end + + def self.down + remove_column :taxons, :description + end +end diff --git a/spec/test_app/db/migrate/20100528155333_index_for_shipments_number.rb b/spec/test_app/db/migrate/20100528155333_index_for_shipments_number.rb new file mode 100644 index 0000000..b33ca2f --- /dev/null +++ b/spec/test_app/db/migrate/20100528155333_index_for_shipments_number.rb @@ -0,0 +1,9 @@ +class IndexForShipmentsNumber < ActiveRecord::Migration + def self.up + add_index :shipments, :number + end + + def self.down + remove_index :shipments, :number + end +end diff --git a/spec/test_app/db/migrate/20100528185820_add_index_on_users_persistence_token.rb b/spec/test_app/db/migrate/20100528185820_add_index_on_users_persistence_token.rb new file mode 100644 index 0000000..2905e9e --- /dev/null +++ b/spec/test_app/db/migrate/20100528185820_add_index_on_users_persistence_token.rb @@ -0,0 +1,9 @@ +class AddIndexOnUsersPersistenceToken < ActiveRecord::Migration + def self.up + add_index :users, :persistence_token + end + + def self.down + remove_index :users, :persistence_token + end +end diff --git a/spec/test_app/db/migrate/20100605152042_add_default_to_tax_categories.rb b/spec/test_app/db/migrate/20100605152042_add_default_to_tax_categories.rb new file mode 100644 index 0000000..e2ea792 --- /dev/null +++ b/spec/test_app/db/migrate/20100605152042_add_default_to_tax_categories.rb @@ -0,0 +1,9 @@ +class AddDefaultToTaxCategories < ActiveRecord::Migration + def self.up + add_column :tax_categories, :is_default, :boolean, :default => false + end + + def self.down + remove_column :tax_categories, :is_default + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20100624110730_add_display_to_shipping_methods.rb b/spec/test_app/db/migrate/20100624110730_add_display_to_shipping_methods.rb new file mode 100644 index 0000000..f14bea6 --- /dev/null +++ b/spec/test_app/db/migrate/20100624110730_add_display_to_shipping_methods.rb @@ -0,0 +1,9 @@ +class AddDisplayToShippingMethods < ActiveRecord::Migration + def self.up + add_column :shipping_methods, :display_on, :string, :default => nil + end + + def self.down + remove_column :shipping_methods, :display_on + end +end diff --git a/spec/test_app/db/migrate/20100624123336_rename_payment_method_display.rb b/spec/test_app/db/migrate/20100624123336_rename_payment_method_display.rb new file mode 100644 index 0000000..6240453 --- /dev/null +++ b/spec/test_app/db/migrate/20100624123336_rename_payment_method_display.rb @@ -0,0 +1,9 @@ +class RenamePaymentMethodDisplay < ActiveRecord::Migration + def self.up + rename_column :payment_methods, :display, :display_on + end + + def self.down + rename_column :payment_methods, :display_on, :display + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20100624175547_rename_preferences_field.rb b/spec/test_app/db/migrate/20100624175547_rename_preferences_field.rb new file mode 100644 index 0000000..613ee3a --- /dev/null +++ b/spec/test_app/db/migrate/20100624175547_rename_preferences_field.rb @@ -0,0 +1,8 @@ +class RenamePreferencesField < ActiveRecord::Migration + def self.up + rename_column(:preferences, :attribute, :name) + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20100811163637_add_guest_flag.rb b/spec/test_app/db/migrate/20100811163637_add_guest_flag.rb new file mode 100644 index 0000000..1df2fa4 --- /dev/null +++ b/spec/test_app/db/migrate/20100811163637_add_guest_flag.rb @@ -0,0 +1,13 @@ +class AddGuestFlag < ActiveRecord::Migration + def self.up + change_table :users do |t| + t.boolean :guest + end + end + + def self.down + change_table :users do |t| + t.remove :guest + end + end +end diff --git a/spec/test_app/db/migrate/20100811205836_drop_order_token.rb b/spec/test_app/db/migrate/20100811205836_drop_order_token.rb new file mode 100644 index 0000000..760cab3 --- /dev/null +++ b/spec/test_app/db/migrate/20100811205836_drop_order_token.rb @@ -0,0 +1,11 @@ +class DropOrderToken < ActiveRecord::Migration + def self.up + change_table :orders do |t| + t.remove :token + end + end + + def self.down + # no going back + end +end diff --git a/spec/test_app/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb b/spec/test_app/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb new file mode 100644 index 0000000..1737555 --- /dev/null +++ b/spec/test_app/db/migrate/20100812162326_payments_state_and_assigned_to_order_only.rb @@ -0,0 +1,11 @@ +class PaymentsStateAndAssignedToOrderOnly < ActiveRecord::Migration + def self.up + # TODO: migrate existing payments + rename_column :payments, :payable_id, :order_id + remove_column :payments, :payable_type + add_column :payments, :state, :string + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20100813023502_create_address_keys_for_order.rb b/spec/test_app/db/migrate/20100813023502_create_address_keys_for_order.rb new file mode 100644 index 0000000..bf44320 --- /dev/null +++ b/spec/test_app/db/migrate/20100813023502_create_address_keys_for_order.rb @@ -0,0 +1,15 @@ +class CreateAddressKeysForOrder < ActiveRecord::Migration + def self.up + change_table :orders do |t| + t.integer :bill_address_id + t.integer :ship_address_id + end + end + + def self.down + change_table :orders do |t| + t.remove :bill_address_id + t.remove :ship_address_id + end + end +end diff --git a/spec/test_app/db/migrate/20100813185745_payment_total_for_orders.rb b/spec/test_app/db/migrate/20100813185745_payment_total_for_orders.rb new file mode 100644 index 0000000..3a89bd0 --- /dev/null +++ b/spec/test_app/db/migrate/20100813185745_payment_total_for_orders.rb @@ -0,0 +1,9 @@ +class PaymentTotalForOrders < ActiveRecord::Migration + def self.up + add_column :orders, :payment_total, :decimal, :precision => 8, :scale => 2, :default => 0.0 + end + + def self.down + remove_column :orders, :payment_total + end +end diff --git a/spec/test_app/db/migrate/20100816212146_shipping_method_id_for_orders.rb b/spec/test_app/db/migrate/20100816212146_shipping_method_id_for_orders.rb new file mode 100644 index 0000000..f972985 --- /dev/null +++ b/spec/test_app/db/migrate/20100816212146_shipping_method_id_for_orders.rb @@ -0,0 +1,9 @@ +class ShippingMethodIdForOrders < ActiveRecord::Migration + def self.up + add_column :orders, :shipping_method_id, :integer + end + + def self.down + remove_column :orders, :shipping_method_id + end +end diff --git a/spec/test_app/db/migrate/20100817152723_add_shipment_and_payment_state.rb b/spec/test_app/db/migrate/20100817152723_add_shipment_and_payment_state.rb new file mode 100644 index 0000000..60f2992 --- /dev/null +++ b/spec/test_app/db/migrate/20100817152723_add_shipment_and_payment_state.rb @@ -0,0 +1,15 @@ +class AddShipmentAndPaymentState < ActiveRecord::Migration + def self.up + change_table :orders do |t| + t.string :shipment_state + t.string :payment_state + end + end + + def self.down + change_table :orders do |t| + t.remove :shipment_state + t.remove :payment_state + end + end +end diff --git a/spec/test_app/db/migrate/20100819170125_refactor_adjustments.rb b/spec/test_app/db/migrate/20100819170125_refactor_adjustments.rb new file mode 100644 index 0000000..3a8d28b --- /dev/null +++ b/spec/test_app/db/migrate/20100819170125_refactor_adjustments.rb @@ -0,0 +1,19 @@ +class RefactorAdjustments < ActiveRecord::Migration + def self.up + change_table :adjustments do |t| + t.boolean :mandatory + t.boolean :frozen + t.rename :adjustment_source_id, :source_id + t.rename :adjustment_source_type, :source_type + t.references :originator + t.string :originator_type + t.remove :type + t.rename :description, :label + t.remove :position + end + end + + def self.down + # no going back + end +end diff --git a/spec/test_app/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb b/spec/test_app/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb new file mode 100644 index 0000000..d504381 --- /dev/null +++ b/spec/test_app/db/migrate/20100820135707_response_code_and_avs_response_for_payments.rb @@ -0,0 +1,11 @@ +class ResponseCodeAndAvsResponseForPayments < ActiveRecord::Migration + def self.up + add_column :payments, :response_code, :string + add_column :payments, :avs_response, :string + end + + def self.down + remove_column :payments, :response_code + remove_column :payments, :avs_response + end +end diff --git a/spec/test_app/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb b/spec/test_app/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb new file mode 100644 index 0000000..0fd9378 --- /dev/null +++ b/spec/test_app/db/migrate/20100901171814_change_guest_flag_to_anonymous.rb @@ -0,0 +1,13 @@ +class ChangeGuestFlagToAnonymous < ActiveRecord::Migration + def self.up + change_table :users do |t| + t.rename :guest, :anonymous + end + end + + def self.down + change_table :users do |t| + t.rename :anonymous, :guest + end + end +end diff --git a/spec/test_app/db/migrate/20100903203949_email_for_orders.rb b/spec/test_app/db/migrate/20100903203949_email_for_orders.rb new file mode 100644 index 0000000..c0d5bef --- /dev/null +++ b/spec/test_app/db/migrate/20100903203949_email_for_orders.rb @@ -0,0 +1,9 @@ +class EmailForOrders < ActiveRecord::Migration + def self.up + add_column :orders, :email, :string + end + + def self.down + remove_column :orders, :email + end +end diff --git a/spec/test_app/db/migrate/20100923162011_create_mail_methods.rb b/spec/test_app/db/migrate/20100923162011_create_mail_methods.rb new file mode 100644 index 0000000..e4141cc --- /dev/null +++ b/spec/test_app/db/migrate/20100923162011_create_mail_methods.rb @@ -0,0 +1,12 @@ +class CreateMailMethods < ActiveRecord::Migration + def self.up + create_table :mail_methods do |t| + t.string :environment + t.boolean :active, :default => true + t.timestamps + end + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20100929151905_rename_frozen_to_locked.rb b/spec/test_app/db/migrate/20100929151905_rename_frozen_to_locked.rb new file mode 100644 index 0000000..b78b4f7 --- /dev/null +++ b/spec/test_app/db/migrate/20100929151905_rename_frozen_to_locked.rb @@ -0,0 +1,8 @@ +class RenameFrozenToLocked < ActiveRecord::Migration + def self.up + rename_column :adjustments, :frozen, :locked + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101008190536_move_special_instructions_to_orders.rb b/spec/test_app/db/migrate/20101008190536_move_special_instructions_to_orders.rb new file mode 100644 index 0000000..fcd04c5 --- /dev/null +++ b/spec/test_app/db/migrate/20101008190536_move_special_instructions_to_orders.rb @@ -0,0 +1,11 @@ +class MoveSpecialInstructionsToOrders < ActiveRecord::Migration + def self.up + add_column :orders, :special_instructions, :text + + ActiveRecord::Base.connection.execute("update orders set special_instructions = (select special_instructions from checkouts where order_id = orders.id)") + end + + def self.down + remove_column :orders, :special_instructions, :text + end +end diff --git a/spec/test_app/db/migrate/20101026184700_create_log_entries.rb b/spec/test_app/db/migrate/20101026184700_create_log_entries.rb new file mode 100644 index 0000000..d135d97 --- /dev/null +++ b/spec/test_app/db/migrate/20101026184700_create_log_entries.rb @@ -0,0 +1,15 @@ +class CreateLogEntries < ActiveRecord::Migration + def self.up + create_table :log_entries do |t| + t.integer :source_id + t.string :source_type + t.text :details + + t.timestamps + end + end + + def self.down + drop_table :log_entries + end +end diff --git a/spec/test_app/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb b/spec/test_app/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb new file mode 100644 index 0000000..f5bd5ea --- /dev/null +++ b/spec/test_app/db/migrate/20101026184714_migrate_transactions_to_payment_state.rb @@ -0,0 +1,94 @@ +class Transaction < ActiveRecord::Base; end +class CreditcardTxn < Transaction; end + +class MigrateTransactionsToPaymentState < ActiveRecord::Migration + + AUTHORIZED=1 + COMPLETED=2 + PURCHASED=3 + VOIDED = 4 + CREDITED =5 + + PAYMENT_COMPLETE = 'completed' + PAYMENT_VOID = 'void' + PAYMENT_PENDING = 'pending' + + def self.up + migrate_authorized_only_transactions + migrate_voided_transactions + migrate_completed_transactions + migrate_purchased_transactions + migrate_credited_transactions + end + + def self.migrate_credited_transactions + credited = Transaction.find_by_sql("select * from transactions where txn_type = #{CREDITED}") + credited.each do |tx| + payment = Payment.find(tx) + order = payment.order + order.create_payment( + :amount=>tx.amount, + :source_id=>payment.source_id, :source_type=>'Creditcard', + :payment_method_id=>payment.payment_method_id, :state=>PAYMENT_COMPLETE, + :avs_response=>tx.avs_response, :response_code=>tx.response_code + ) + end + credited.each{|rec| rec.destroy } + end + + def self.migrate_voided_transactions + voided = Transaction.find_by_sql("select * from transactions where txn_type=#{VOIDED}") + voided.each do |tx| + update_payment(tx, PAYMENT_VOID) + end + unless voided.empty? + all_but_credited = [AUTHORIZED, COMPLETED, PURCHASED, VOIDED] + voided_and_subsequent_transactions = Transaction.find_by_sql("select * from transactions where payment_id in (#{voided.map(&:payment_id).join(',')}) and txn_type in (#{all_but_credited.join(',')})") + voided_and_subsequent_transactions.each{|rec| rec.destroy } + end + end + + def self.migrate_purchased_transactions + migrate_transactions(PURCHASED) + end + + def self.migrate_completed_transactions + migrate_transactions(COMPLETED) + end + + def self.migrate_transactions(type) + txs = Transaction.find_by_sql("select * from transactions where txn_type = #{type}") + txs.each do |tx| + update_payment(tx, PAYMENT_COMPLETE) + end + txs.each{|rec| rec.destroy } + end + + def self.migrate_authorized_only_transactions + if (ActiveRecord::Base.connection.adapter_name == 'PostgreSQL') + group_by_clause = "group by transactions." + Transaction.column_names.join(", transactions.") + else + group_by_clause = "group by payment_id" + end + authorized_only = Transaction.find_by_sql("select * from transactions #{group_by_clause} having count(payment_id) = 1 and txn_type = #{AUTHORIZED}") + authorized_only.each do |tx| + update_payment(tx, PAYMENT_PENDING) + end + authorized_only.each {|rec| rec.destroy } + end + + def self.update_payment(tx, state) + payment = Payment.find(tx.payment_id) + payment.update_attributes_without_callbacks({ + :state => state, + :source_type => 'Creditcard', + :amount => tx.amount, + :response_code => tx.response_code, + :avs_response => tx.avs_response + }) + end + + def self.down + end +end + diff --git a/spec/test_app/db/migrate/20101026184746_delete_in_progress_orders.rb b/spec/test_app/db/migrate/20101026184746_delete_in_progress_orders.rb new file mode 100644 index 0000000..6f4b461 --- /dev/null +++ b/spec/test_app/db/migrate/20101026184746_delete_in_progress_orders.rb @@ -0,0 +1,18 @@ +class DeleteInProgressOrders < ActiveRecord::Migration + def self.up + Order.delete_all(:state=>'in_progress') + delete_orphans('adjustments') + delete_orphans('checkouts') + delete_orphans('shipments') + delete_orphans('payments') + delete_orphans('line_items') + delete_orphans('inventory_units') + end + + def self.delete_orphans(table_name) + execute("delete from #{table_name} where order_id not in (select id from orders)") + end + + def self.down + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20101026184808_migrate_checkout_to_orders.rb b/spec/test_app/db/migrate/20101026184808_migrate_checkout_to_orders.rb new file mode 100644 index 0000000..d55e3fe --- /dev/null +++ b/spec/test_app/db/migrate/20101026184808_migrate_checkout_to_orders.rb @@ -0,0 +1,27 @@ +class MigrateCheckoutToOrders < ActiveRecord::Migration + + class Checkout < ActiveRecord::Base + end + + def self.up + Order.find_each do |order| + checkout = update_order(order) + checkout.destroy if checkout + end + end + + def self.update_order(order) + checkout = Checkout.find_by_order_id(order.id) + if checkout + order.update_attributes_without_callbacks({ + :email => checkout.email, + :bill_address_id => checkout.bill_address_id, + :ship_address_id => checkout.ship_address_id + }) + end + checkout + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101026184833_migrate_adjustments.rb b/spec/test_app/db/migrate/20101026184833_migrate_adjustments.rb new file mode 100644 index 0000000..d5ded8e --- /dev/null +++ b/spec/test_app/db/migrate/20101026184833_migrate_adjustments.rb @@ -0,0 +1,9 @@ +class MigrateAdjustments < ActiveRecord::Migration + def self.up + execute("update adjustments set amount = 0.0 where amount is null") + execute("update adjustments set mandatory = 'true', locked = 'true'") + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101026184855_remove_shipped_state.rb b/spec/test_app/db/migrate/20101026184855_remove_shipped_state.rb new file mode 100644 index 0000000..377cf0a --- /dev/null +++ b/spec/test_app/db/migrate/20101026184855_remove_shipped_state.rb @@ -0,0 +1,14 @@ +class RemoveShippedState < ActiveRecord::Migration + def self.up + Order.where(:state => 'shipped').each do |order| + order.update_attribute_without_callbacks("state", "complete") + order.shipments.each do |shipment| + shipment.state = 'shipped' + shipment.save + end + end + end + + def self.down + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20101026184916_prevent_nil_payment_total.rb b/spec/test_app/db/migrate/20101026184916_prevent_nil_payment_total.rb new file mode 100644 index 0000000..d1b9d8a --- /dev/null +++ b/spec/test_app/db/migrate/20101026184916_prevent_nil_payment_total.rb @@ -0,0 +1,8 @@ +class PreventNilPaymentTotal < ActiveRecord::Migration + def self.up + execute("update orders set payment_total = 0.0 where payment_total is null") + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101026184932_prevent_nil_email.rb b/spec/test_app/db/migrate/20101026184932_prevent_nil_email.rb new file mode 100644 index 0000000..bf11421 --- /dev/null +++ b/spec/test_app/db/migrate/20101026184932_prevent_nil_email.rb @@ -0,0 +1,9 @@ +class PreventNilEmail < ActiveRecord::Migration + def self.up + execute("update orders set email = 'guest@example.com' where email is null") + execute("update orders set email = 'guest@example.com' where email = ''") + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101026184959_generate_anonymous_users.rb b/spec/test_app/db/migrate/20101026184959_generate_anonymous_users.rb new file mode 100644 index 0000000..f87e5fa --- /dev/null +++ b/spec/test_app/db/migrate/20101026184959_generate_anonymous_users.rb @@ -0,0 +1,14 @@ +class GenerateAnonymousUsers < ActiveRecord::Migration + def self.up + User.reset_column_information + Order.where(:user_id => nil).each do |order| + user = User.anonymous! + user.email ||= order.email + order.user = user + order.save! + end + end + + def self.down + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20101026185022_update_order_state.rb b/spec/test_app/db/migrate/20101026185022_update_order_state.rb new file mode 100644 index 0000000..1eff98e --- /dev/null +++ b/spec/test_app/db/migrate/20101026185022_update_order_state.rb @@ -0,0 +1,8 @@ +class UpdateOrderState < ActiveRecord::Migration + def self.up + Order.all.map(&:update!) + end + + def self.down + end +end \ No newline at end of file diff --git a/spec/test_app/db/migrate/20101026192225_cleanup_legacy_tables.rb b/spec/test_app/db/migrate/20101026192225_cleanup_legacy_tables.rb new file mode 100644 index 0000000..3984afb --- /dev/null +++ b/spec/test_app/db/migrate/20101026192225_cleanup_legacy_tables.rb @@ -0,0 +1,11 @@ +class CleanupLegacyTables < ActiveRecord::Migration + def self.up + drop_table :checkouts + drop_table :transactions + drop_table :open_id_authentication_associations + drop_table :open_id_authentication_nonces + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb b/spec/test_app/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb new file mode 100644 index 0000000..d71904b --- /dev/null +++ b/spec/test_app/db/migrate/20101028151745_remove_number_and_cvv_from_credicard.rb @@ -0,0 +1,9 @@ +class RemoveNumberAndCvvFromCredicard < ActiveRecord::Migration + def self.up + remove_column :creditcards, :number + remove_column :creditcards, :verification_value + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101103212716_drop_anonymous_field_for_user.rb b/spec/test_app/db/migrate/20101103212716_drop_anonymous_field_for_user.rb new file mode 100644 index 0000000..588cf70 --- /dev/null +++ b/spec/test_app/db/migrate/20101103212716_drop_anonymous_field_for_user.rb @@ -0,0 +1,8 @@ +class DropAnonymousFieldForUser < ActiveRecord::Migration + def self.up + remove_column :users, :anonymous + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101111133551_renamed_rma_cancelled_state.rb b/spec/test_app/db/migrate/20101111133551_renamed_rma_cancelled_state.rb new file mode 100644 index 0000000..de97224 --- /dev/null +++ b/spec/test_app/db/migrate/20101111133551_renamed_rma_cancelled_state.rb @@ -0,0 +1,10 @@ +class RenamedRmaCancelledState < ActiveRecord::Migration + def self.up + ReturnAuthorization.where(:state => 'cancelled').each do |rma| + rma.update_attribute_without_callbacks(:state, 'canceled') + end + end + + def self.down + end +end diff --git a/spec/test_app/db/migrate/20101117031806_fix_problematic_index_names.rb b/spec/test_app/db/migrate/20101117031806_fix_problematic_index_names.rb new file mode 100644 index 0000000..bca6762 --- /dev/null +++ b/spec/test_app/db/migrate/20101117031806_fix_problematic_index_names.rb @@ -0,0 +1,13 @@ +class FixProblematicIndexNames < ActiveRecord::Migration + def self.up + begin + remove_index("preferences", "index_preferences_on_owner_and_attribute_and_preference") + rescue ArgumentError + # ignore - already remove then + end + add_index "preferences", ["owner_id", "owner_type", "name", "group_id", "group_type"], :name => "ix_prefs_on_owner_attr_pref", :unique => true + end + + def self.down + end +end diff --git a/spec/test_app/db/sample/users.rb b/spec/test_app/db/sample/users.rb new file mode 100644 index 0000000..3e06b47 --- /dev/null +++ b/spec/test_app/db/sample/users.rb @@ -0,0 +1,53 @@ +# see last line where we create an admin if there is none, asking for email and password +def prompt_for_admin_password + password = ask('Password [spree123]: ', String) do |q| + q.echo = false + q.validate = /^(|.{5,40})$/ + q.responses[:not_valid] = "Invalid password. Must be at least 5 characters long." + q.whitespace = :strip + end + password = "spree123" if password.blank? + password +end + +def prompt_for_admin_email + email = ask('Email [spree@example.com]: ', String) do |q| + q.echo = true + q.whitespace = :strip + end + email = "spree@example.com" if email.blank? + email +end + +def create_admin_user + if ENV['AUTO_ACCEPT'] + password = "spree" + email = "spree@example.com" + else + require 'highline/import' + puts "Create the admin user (press enter for defaults)." + #name = prompt_for_admin_name unless name + email = prompt_for_admin_email + password = prompt_for_admin_password + end + attributes = { + :password => password, + :password_confirmation => password, + :email => email, + :login => email + } + + load 'user.rb' + + if User.find_by_email(email) + say "\nWARNING: There is already a user with the email: #{email}, so no account changes were made. If you wish to create an additional admin user, please run rake db:admin:create again with a different email.\n\n" + else + admin = User.create(attributes) + # create an admin role and and assign the admin user to that role + role = Role.find_or_create_by_name "admin" + admin.roles << role + admin.save + end +end + +create_admin_user if User.where("roles.name" => 'admin').includes(:roles).empty? \ No newline at end of file diff --git a/spec/test_app/db/schema.rb b/spec/test_app/db/schema.rb new file mode 100644 index 0000000..a63bc8a --- /dev/null +++ b/spec/test_app/db/schema.rb @@ -0,0 +1,543 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended to check this file into your version control system. + +ActiveRecord::Schema.define(:version => 20101117031806) do + + create_table "addresses", :force => true do |t| + t.string "firstname" + t.string "lastname" + t.string "address1" + t.string "address2" + t.string "city" + t.integer "state_id" + t.string "zipcode" + t.integer "country_id" + t.string "phone" + t.datetime "created_at" + t.datetime "updated_at" + t.string "state_name" + t.string "alternative_phone" + end + + add_index "addresses", ["firstname"], :name => "index_addresses_on_firstname" + add_index "addresses", ["lastname"], :name => "index_addresses_on_lastname" + + create_table "adjustments", :force => true do |t| + t.integer "order_id" + t.decimal "amount" + t.string "label" + t.datetime "created_at" + t.datetime "updated_at" + t.integer "source_id" + t.string "source_type" + t.boolean "mandatory" + t.boolean "locked" + t.integer "originator_id" + t.string "originator_type" + end + + add_index "adjustments", ["order_id"], :name => "index_adjustments_on_order_id" + + create_table "assets", :force => true do |t| + t.integer "viewable_id" + t.string "viewable_type", :limit => 50 + t.string "attachment_content_type" + t.string "attachment_file_name" + t.integer "attachment_size" + t.integer "position" + t.string "type", :limit => 75 + t.datetime "attachment_updated_at" + t.integer "attachment_width" + t.integer "attachment_height" + t.text "alt" + end + + add_index "assets", ["viewable_id"], :name => "index_assets_on_viewable_id" + add_index "assets", ["viewable_type", "type"], :name => "index_assets_on_viewable_type_and_type" + + create_table "calculators", :force => true do |t| + t.string "type" + t.integer "calculable_id", :null => false + t.string "calculable_type", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "configurations", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "type", :limit => 50 + end + + add_index "configurations", ["name", "type"], :name => "index_configurations_on_name_and_type" + + create_table "countries", :force => true do |t| + t.string "iso_name" + t.string "iso" + t.string "name" + t.string "iso3" + t.integer "numcode" + end + + create_table "coupons", :force => true do |t| + t.string "code" + t.string "description" + t.integer "usage_limit" + t.boolean "combine" + t.datetime "expires_at" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "starts_at" + end + + create_table "creditcards", :force => true do |t| + t.string "month" + t.string "year" + t.string "cc_type" + t.string "last_digits" + t.string "first_name" + t.string "last_name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "start_month" + t.string "start_year" + t.string "issue_number" + t.integer "address_id" + t.string "gateway_customer_profile_id" + t.string "gateway_payment_profile_id" + end + + create_table "gateways", :force => true do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", :default => true + t.string "environment", :default => "development" + t.string "server", :default => "test" + t.boolean "test_mode", :default => true + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "inventory_units", :force => true do |t| + t.integer "variant_id" + t.integer "order_id" + t.string "state" + t.integer "lock_version", :default => 0 + t.datetime "created_at" + t.datetime "updated_at" + t.integer "shipment_id" + t.integer "return_authorization_id" + end + + add_index "inventory_units", ["order_id"], :name => "index_inventory_units_on_order_id" + add_index "inventory_units", ["shipment_id"], :name => "index_inventory_units_on_shipment_id" + add_index "inventory_units", ["variant_id"], :name => "index_inventory_units_on_variant_id" + + create_table "line_items", :force => true do |t| + t.integer "order_id" + t.integer "variant_id" + t.integer "quantity", :null => false + t.decimal "price", :precision => 8, :scale => 2, :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "line_items", ["order_id"], :name => "index_line_items_on_order_id" + add_index "line_items", ["variant_id"], :name => "index_line_items_on_variant_id" + + create_table "log_entries", :force => true do |t| + t.integer "source_id" + t.string "source_type" + t.text "details" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "mail_methods", :force => true do |t| + t.string "environment" + t.boolean "active", :default => true + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "option_types", :force => true do |t| + t.string "name", :limit => 100 + t.string "presentation", :limit => 100 + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "option_types_prototypes", :id => false, :force => true do |t| + t.integer "prototype_id" + t.integer "option_type_id" + end + + create_table "option_values", :force => true do |t| + t.integer "option_type_id" + t.string "name" + t.integer "position" + t.string "presentation" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "option_values_variants", :id => false, :force => true do |t| + t.integer "variant_id" + t.integer "option_value_id" + end + + add_index "option_values_variants", ["variant_id", "option_value_id"], :name => "index_option_values_variants_on_variant_id_and_option_value_id" + add_index "option_values_variants", ["variant_id"], :name => "index_option_values_variants_on_variant_id" + + create_table "orders", :force => true do |t| + t.integer "user_id" + t.string "number", :limit => 15 + t.decimal "item_total", :default => 0.0, :null => false + t.decimal "total", :default => 0.0, :null => false + t.datetime "created_at" + t.datetime "updated_at" + t.string "state" + t.decimal "adjustment_total", :default => 0.0, :null => false + t.decimal "credit_total", :default => 0.0, :null => false + t.datetime "completed_at" + t.integer "bill_address_id" + t.integer "ship_address_id" + t.decimal "payment_total", :precision => 8, :scale => 2, :default => 0.0 + t.integer "shipping_method_id" + t.string "shipment_state" + t.string "payment_state" + t.string "email" + t.text "special_instructions" + end + + add_index "orders", ["number"], :name => "index_orders_on_number" + + create_table "payment_methods", :force => true do |t| + t.string "type" + t.string "name" + t.text "description" + t.boolean "active", :default => true + t.string "environment", :default => "development" + t.datetime "created_at" + t.datetime "updated_at" + t.datetime "deleted_at" + t.string "display_on" + end + + create_table "payments", :force => true do |t| + t.integer "order_id" + t.datetime "created_at" + t.datetime "updated_at" + t.decimal "amount", :default => 0.0, :null => false + t.integer "source_id" + t.string "source_type" + t.integer "payment_method_id" + t.string "state" + t.string "response_code" + t.string "avs_response" + end + + create_table "preferences", :force => true do |t| + t.string "name", :limit => 100, :null => false + t.integer "owner_id", :limit => 30, :null => false + t.string "owner_type", :limit => 50, :null => false + t.integer "group_id" + t.string "group_type", :limit => 50 + t.text "value", :limit => 255 + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "preferences", ["owner_id", "owner_type", "name", "group_id", "group_type"], :name => "ix_prefs_on_owner_attr_pref", :unique => true + + create_table "product_groups", :force => true do |t| + t.string "name" + t.string "permalink" + t.string "order" + end + + add_index "product_groups", ["name"], :name => "index_product_groups_on_name" + add_index "product_groups", ["permalink"], :name => "index_product_groups_on_permalink" + + create_table "product_groups_products", :id => false, :force => true do |t| + t.integer "product_id" + t.integer "product_group_id" + end + + create_table "product_option_types", :force => true do |t| + t.integer "product_id" + t.integer "option_type_id" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "product_properties", :force => true do |t| + t.integer "product_id" + t.integer "property_id" + t.string "value" + t.datetime "created_at" + t.datetime "updated_at" + end + + add_index "product_properties", ["product_id"], :name => "index_product_properties_on_product_id" + + create_table "product_scopes", :force => true do |t| + t.integer "product_group_id" + t.string "name" + t.text "arguments" + end + + add_index "product_scopes", ["name"], :name => "index_product_scopes_on_name" + add_index "product_scopes", ["product_group_id"], :name => "index_product_scopes_on_product_group_id" + + create_table "products", :force => true do |t| + t.string "name", :default => "", :null => false + t.text "description" + t.datetime "created_at" + t.datetime "updated_at" + t.string "permalink" + t.datetime "available_on" + t.integer "tax_category_id" + t.integer "shipping_category_id" + t.datetime "deleted_at" + t.string "meta_description" + t.string "meta_keywords" + t.integer "count_on_hand", :default => 0, :null => false + end + + add_index "products", ["available_on"], :name => "index_products_on_available_on" + add_index "products", ["deleted_at"], :name => "index_products_on_deleted_at" + add_index "products", ["name"], :name => "index_products_on_name" + add_index "products", ["permalink"], :name => "index_products_on_permalink" + + create_table "products_taxons", :id => false, :force => true do |t| + t.integer "product_id" + t.integer "taxon_id" + end + + add_index "products_taxons", ["product_id"], :name => "index_products_taxons_on_product_id" + add_index "products_taxons", ["taxon_id"], :name => "index_products_taxons_on_taxon_id" + + create_table "properties", :force => true do |t| + t.string "name" + t.string "presentation", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "properties_prototypes", :id => false, :force => true do |t| + t.integer "prototype_id" + t.integer "property_id" + end + + create_table "prototypes", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "question_categories", :force => true do |t| + t.string "name" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "questions", :force => true do |t| + t.integer "question_category_id" + t.text "question" + t.text "answer" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "return_authorizations", :force => true do |t| + t.string "number" + t.decimal "amount", :precision => 8, :scale => 2, :default => 0.0, :null => false + t.integer "order_id" + t.text "reason" + t.string "state" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "roles", :force => true do |t| + t.string "name" + end + + create_table "roles_users", :id => false, :force => true do |t| + t.integer "role_id" + t.integer "user_id" + end + + add_index "roles_users", ["role_id"], :name => "index_roles_users_on_role_id" + add_index "roles_users", ["user_id"], :name => "index_roles_users_on_user_id" + + create_table "shipments", :force => true do |t| + t.integer "order_id" + t.integer "shipping_method_id" + t.string "tracking" + t.datetime "created_at" + t.datetime "updated_at" + t.string "number" + t.decimal "cost", :precision => 8, :scale => 2 + t.datetime "shipped_at" + t.integer "address_id" + t.string "state" + end + + add_index "shipments", ["number"], :name => "index_shipments_on_number" + + create_table "shipping_categories", :force => true do |t| + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "shipping_methods", :force => true do |t| + t.integer "zone_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "display_on" + end + + create_table "state_events", :force => true do |t| + t.integer "stateful_id" + t.integer "user_id" + t.string "name" + t.datetime "created_at" + t.datetime "updated_at" + t.string "previous_state" + t.string "stateful_type" + end + + create_table "states", :force => true do |t| + t.string "name" + t.string "abbr" + t.integer "country_id" + end + + create_table "tax_categories", :force => true do |t| + t.string "name" + t.string "description" + t.datetime "created_at" + t.datetime "updated_at" + t.boolean "is_default", :default => false + end + + create_table "tax_rates", :force => true do |t| + t.integer "zone_id" + t.decimal "amount", :precision => 8, :scale => 4 + t.datetime "created_at" + t.datetime "updated_at" + t.integer "tax_category_id" + end + + create_table "taxonomies", :force => true do |t| + t.string "name", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "taxons", :force => true do |t| + t.integer "taxonomy_id", :null => false + t.integer "parent_id" + t.integer "position", :default => 0 + t.string "name", :null => false + t.datetime "created_at" + t.datetime "updated_at" + t.string "permalink" + t.integer "lft" + t.integer "rgt" + t.string "icon_file_name" + t.string "icon_content_type" + t.integer "icon_file_size" + t.datetime "icon_updated_at" + t.text "description" + end + + add_index "taxons", ["parent_id"], :name => "index_taxons_on_parent_id" + add_index "taxons", ["permalink"], :name => "index_taxons_on_permalink" + add_index "taxons", ["taxonomy_id"], :name => "index_taxons_on_taxonomy_id" + + create_table "trackers", :force => true do |t| + t.string "environment" + t.string "analytics_id" + t.boolean "active", :default => true + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "users", :force => true do |t| + t.string "email" + t.string "crypted_password", :limit => 128 + t.string "salt", :limit => 128 + t.string "remember_token" + t.string "remember_token_expires_at" + t.datetime "created_at" + t.datetime "updated_at" + t.string "persistence_token" + t.string "single_access_token" + t.string "perishable_token" + t.integer "login_count", :default => 0, :null => false + t.integer "failed_login_count", :default => 0, :null => false + t.datetime "last_request_at" + t.datetime "current_login_at" + t.datetime "last_login_at" + t.string "current_login_ip" + t.string "last_login_ip" + t.string "login" + t.integer "ship_address_id" + t.integer "bill_address_id" + t.string "openid_identifier" + end + + add_index "users", ["openid_identifier"], :name => "index_users_on_openid_identifier" + add_index "users", ["persistence_token"], :name => "index_users_on_persistence_token" + + create_table "variants", :force => true do |t| + t.integer "product_id" + t.string "sku", :default => "", :null => false + t.decimal "price", :precision => 8, :scale => 2, :null => false + t.decimal "weight", :precision => 8, :scale => 2 + t.decimal "height", :precision => 8, :scale => 2 + t.decimal "width", :precision => 8, :scale => 2 + t.decimal "depth", :precision => 8, :scale => 2 + t.datetime "deleted_at" + t.boolean "is_master", :default => false + t.integer "count_on_hand", :default => 0, :null => false + t.decimal "cost_price", :precision => 8, :scale => 2 + end + + add_index "variants", ["product_id"], :name => "index_variants_on_product_id" + + create_table "zone_members", :force => true do |t| + t.integer "zone_id" + t.integer "zoneable_id" + t.string "zoneable_type" + t.datetime "created_at" + t.datetime "updated_at" + end + + create_table "zones", :force => true do |t| + t.string "name" + t.string "description" + t.datetime "created_at" + t.datetime "updated_at" + end + +end diff --git a/spec/test_app/db/seeds.rb b/spec/test_app/db/seeds.rb new file mode 100644 index 0000000..3cc1fda --- /dev/null +++ b/spec/test_app/db/seeds.rb @@ -0,0 +1,3 @@ +# Loads seed data out of default dir +Rake::Task["db:load_dir"].invoke( "default" ) +puts "Default data has been loaded" \ No newline at end of file diff --git a/spec/test_app/db/test.sqlite3 b/spec/test_app/db/test.sqlite3 new file mode 100644 index 0000000000000000000000000000000000000000..9fce6c52a2175ec7bfdfe21b92a80c56a0b16783 GIT binary patch literal 137216 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
y)gT)pU_NuK)i-hh#Mm=~dJEEbN1<>I_l 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 azlK_8J=fDK4EyD8{u0h1^su27h5i52pTjHw literal 0 HcmV?d00001 diff --git a/spec/test_app/log/cucumber.log b/spec/test_app/log/cucumber.log new file mode 100644 index 0000000..9e5a8b6 --- /dev/null +++ b/spec/test_app/log/cucumber.log @@ -0,0 +1,1309 @@ + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) select sqlite_version(*) + SQL (30.0ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)  + SQL (0.1ms) PRAGMA index_list("schema_migrations") + SQL (22.2ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version") + SQL (0.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" +Migrating to CreateQuestions (20090526213535) + SQL (0.7ms) CREATE TABLE "questions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "question_category_id" integer, "question" text, "answer" text, "position" integer, "created_at" datetime, "updated_at" datetime)  + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090526213535') +Migrating to CreateQuestionCategories (20090526213550) + SQL (1.0ms) CREATE TABLE "question_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime) + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090526213550') +Migrating to SpreeZeroNineZero (20090823005402) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.0ms) CREATE TABLE "addresses" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "firstname" varchar(255), "lastname" varchar(255), "address1" varchar(255), "address2" varchar(255), "city" varchar(255), "state_id" integer, "zipcode" varchar(255), "country_id" integer, "phone" varchar(255), "created_at" datetime, "updated_at" datetime, "state_name" varchar(255), "alternative_phone" varchar(255)) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255)) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "assets" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "viewable_id" integer, "viewable_type" varchar(50), "attachment_content_type" varchar(255), "attachment_file_name" varchar(255), "attachment_size" integer, "position" integer, "type" varchar(75), "attachment_updated_at" datetime, "attachment_width" integer, "attachment_height" integer) + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "calculators" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "calculable_id" integer NOT NULL, "calculable_type" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "completed_at" datetime, "created_at" datetime, "updated_at" datetime) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "configurations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "type" varchar(50)) + SQL (0.1ms) PRAGMA index_list("configurations") + SQL (0.3ms) CREATE INDEX "index_configurations_on_name_and_type" ON "configurations" ("name", "type") + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "iso_name" varchar(255), "iso" varchar(255), "name" varchar(255), "iso3" varchar(255), "numcode" integer) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "coupons" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "code" varchar(255), "description" varchar(255), "usage_limit" integer, "combine" boolean, "expires_at" datetime, "created_at" datetime, "updated_at" datetime, "starts_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "creditcard_payment_id" integer, "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "display_number" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "gateway_configurations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "gateway_id" integer, "created_at" datetime, "updated_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "gateway_option_values" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "gateway_configuration_id" integer, "gateway_option_id" integer, "value" text, "created_at" datetime, "updated_at" datetime) + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "gateway_options" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" text, "gateway_id" integer, "textarea" boolean DEFAULT 'f', "created_at" datetime, "updated_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "gateways" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "clazz" varchar(255), "name" varchar(255), "description" text, "active" boolean, "created_at" datetime, "updated_at" datetime) + SQL (0.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "inventory_units" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "variant_id" integer, "order_id" integer, "state" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime) + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "line_items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "variant_id" integer, "quantity" integer NOT NULL, "price" decimal(8,2) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("line_items") + SQL (0.7ms) CREATE INDEX "index_line_items_on_order_id" ON "line_items" ("order_id") + SQL (0.2ms) PRAGMA index_list("line_items") + SQL (0.1ms) PRAGMA index_info('index_line_items_on_order_id') + SQL (0.4ms) CREATE INDEX "index_line_items_on_variant_id" ON "line_items" ("variant_id") + SQL (0.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "option_types" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100), "presentation" varchar(100), "created_at" datetime, "updated_at" datetime)  + SQL (0.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) CREATE TABLE "option_types_prototypes" ("prototype_id" integer, "option_type_id" integer)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "option_values" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "option_type_id" integer, "name" varchar(255), "position" integer, "presentation" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) CREATE TABLE "option_values_variants" ("variant_id" integer, "option_value_id" integer)  + SQL (0.1ms) PRAGMA index_list("option_values_variants") + SQL (0.4ms) CREATE INDEX "index_option_values_variants_on_variant_id" ON "option_values_variants" ("variant_id") + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal(8,2) DEFAULT 0.0 NOT NULL, "total" decimal(8,2) DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "token" varchar(255), "adjustment_total" decimal(8,2) DEFAULT 0.0 NOT NULL, "credit_total" decimal(8,2) DEFAULT 0.0 NOT NULL)  + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.3ms) CREATE INDEX "index_orders_on_number" ON "orders" ("number") + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "creditcard_id" integer, "type" varchar(255))  + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.6ms) CREATE UNIQUE INDEX "index_preferences_on_owner_and_attribute_and_preference" ON "preferences" ("owner_id", "owner_type", "attribute", "group_id", "group_type") + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "product_option_types" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "option_type_id" integer, "position" integer, "created_at" datetime, "updated_at" datetime)  + SQL (3.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.6ms) CREATE TABLE "product_properties" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "property_id" integer, "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT '' NOT NULL, "description" text, "created_at" datetime, "updated_at" datetime, "permalink" varchar(255), "available_on" datetime, "tax_category_id" integer, "shipping_category_id" integer, "deleted_at" datetime, "meta_description" varchar(255), "meta_keywords" varchar(255))  + SQL (0.1ms) PRAGMA index_list("products") + SQL (0.4ms) CREATE INDEX "index_products_on_available_on" ON "products" ("available_on") + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.1ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.3ms) CREATE INDEX "index_products_on_deleted_at" ON "products" ("deleted_at") + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.2ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.2ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.4ms) CREATE INDEX "index_products_on_name" ON "products" ("name") + SQL (0.3ms) PRAGMA index_list("products") + SQL (0.2ms) PRAGMA index_info('index_products_on_name') + SQL (0.2ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.2ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.4ms) CREATE INDEX "index_products_on_permalink" ON "products" ("permalink") + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) CREATE TABLE "products_taxons" ("product_id" integer, "taxon_id" integer)  + SQL (0.1ms) PRAGMA index_list("products_taxons") + SQL (0.4ms) CREATE INDEX "index_products_taxons_on_product_id" ON "products_taxons" ("product_id") + SQL (0.2ms) PRAGMA index_list("products_taxons") + SQL (0.1ms) PRAGMA index_info('index_products_taxons_on_product_id') + SQL (0.3ms) CREATE INDEX "index_products_taxons_on_taxon_id" ON "products_taxons" ("taxon_id") + SQL (0.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "properties" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "presentation" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (0.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "properties_prototypes" ("prototype_id" integer, "property_id" integer) + SQL (0.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "prototypes" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime) + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "roles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)) + SQL (0.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "roles_users" ("role_id" integer, "user_id" integer) + SQL (0.1ms) PRAGMA index_list("roles_users") + SQL (0.4ms) CREATE INDEX "index_roles_users_on_role_id" ON "roles_users" ("role_id") + SQL (0.2ms) PRAGMA index_list("roles_users") + SQL (0.1ms) PRAGMA index_info('index_roles_users_on_role_id') + SQL (0.7ms) CREATE INDEX "index_roles_users_on_user_id" ON "roles_users" ("user_id") + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "shipments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "shipping_method_id" integer, "tracking" varchar(255), "created_at" datetime, "updated_at" datetime, "number" varchar(255), "cost" decimal(8,2), "shipped_at" datetime, "address_id" integer)  + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "shipping_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "shipping_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255))  + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "states" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "abbr" varchar(255), "country_id" integer)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "tax_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "tax_rates" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "amount" decimal(8,4), "created_at" datetime, "updated_at" datetime, "tax_category_id" integer)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "taxonomies" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime)  + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "taxons" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "taxonomy_id" integer NOT NULL, "parent_id" integer, "position" integer DEFAULT 0, "name" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime, "permalink" varchar(255))  + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.9ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer)  + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "variants" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "sku" varchar(255) DEFAULT '' NOT NULL, "price" decimal(8,2) NOT NULL, "weight" decimal(8,2), "height" decimal(8,2), "width" decimal(8,2), "depth" decimal(8,2), "deleted_at" datetime, "is_master" boolean DEFAULT 'f')  + SQL (0.1ms) PRAGMA index_list("variants") + SQL (0.4ms) CREATE INDEX "index_variants_on_product_id" ON "variants" ("product_id") + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "zone_members" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "zoneable_id" integer, "zoneable_type" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "zones" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090823005402') +Migrating to CreateIndexesForInventoryUnits (20090904192342) + SQL (0.1ms) PRAGMA index_list("inventory_units") + SQL (0.6ms) CREATE INDEX "index_inventory_units_on_variant_id" ON "inventory_units" ("variant_id") + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.4ms) CREATE INDEX "index_inventory_units_on_order_id" ON "inventory_units" ("order_id") + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090904192342') +Migrating to AddCountOnHandToVariantsAndProducts (20090923100315) + SQL (0.9ms) ALTER TABLE "variants" ADD "count_on_hand" integer DEFAULT 0 NOT NULL + SQL (1.7ms) ALTER TABLE "products" ADD "count_on_hand" integer DEFAULT 0 NOT NULL + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Variant Load (0.3ms) SELECT "variants".* FROM "variants" + Product Load (0.3ms) SELECT "products".* FROM "products" + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090923100315') +Migrating to ChangeTaxonsToNestedSet (20091007134354) + SQL (0.8ms) ALTER TABLE "taxons" ADD "lft" integer + SQL (0.5ms) ALTER TABLE "taxons" ADD "rgt" integer + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Taxon Load (0.3ms) SELECT "taxons".* FROM "taxons" WHERE (parent_id IS NULL) ORDER BY position ASC + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091007134354') +Migrating to MoveToConfigurableGateways (20091008091614) + SQL (0.6ms) DROP TABLE "gateways" + SQL (0.5ms) DROP TABLE "gateway_options" + SQL (0.4ms) DROP TABLE "gateway_option_values" + SQL (0.4ms) DROP TABLE "gateway_configurations" + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "gateways" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "server" varchar(255) DEFAULT 'test', "test_mode" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091008091614') +Migrating to ProductGroupsAndScopes (20091012120519) + SQL (1.2ms) CREATE TABLE "product_groups" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "permalink" varchar(255), "order" varchar(255))  + SQL (0.5ms) CREATE TABLE "product_scopes" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_group_id" integer, "name" varchar(255), "arguments" text) + SQL (0.1ms) PRAGMA index_list("product_groups") + SQL (0.4ms) CREATE INDEX "index_product_groups_on_name" ON "product_groups" ("name") + SQL (0.2ms) PRAGMA index_list("product_groups") + SQL (0.2ms) PRAGMA index_info('index_product_groups_on_name') + SQL (0.4ms) CREATE INDEX "index_product_groups_on_permalink" ON "product_groups" ("permalink") + SQL (0.1ms) PRAGMA index_list("product_scopes") + SQL (0.4ms) CREATE INDEX "index_product_scopes_on_name" ON "product_scopes" ("name") + SQL (0.2ms) PRAGMA index_list("product_scopes") + SQL (0.2ms) PRAGMA index_info('index_product_scopes_on_name') + SQL (0.4ms) CREATE INDEX "index_product_scopes_on_product_group_id" ON "product_scopes" ("product_group_id") + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091012120519') +Migrating to AddOpenIdAuthenticationTables (20091015110842) + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.9ms) CREATE TABLE "open_id_authentication_associations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "issued" integer, "lifetime" integer, "handle" varchar(255), "assoc_type" varchar(255), "server_url" blob, "secret" blob) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "open_id_authentication_nonces" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "timestamp" integer NOT NULL, "server_url" varchar(255), "salt" varchar(255) NOT NULL) + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091015110842') +Migrating to AddOpenidFieldToUsers (20091015153048) + SQL (0.8ms) ALTER TABLE "users" ADD "openid_identifier" varchar(255) + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.8ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.7ms) DROP TABLE "users" + SQL (0.8ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.6ms) DROP TABLE "altered_users" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.5ms) DROP TABLE "users" + SQL (0.7ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.5ms) DROP TABLE "altered_users" + SQL (1.5ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.4ms) DROP TABLE "users" + SQL (0.5ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.3ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.3ms) DROP TABLE "altered_users" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091015153048') +Migrating to ChangePreferenceValueType (20091016174634) + SQL (0.4ms) PRAGMA index_list("preferences") + SQL (0.3ms) PRAGMA index_info('index_preferences_on_owner_and_attribute_and_preference') + SQL (0.5ms) DROP INDEX "index_preferences_on_owner_and_attribute_and_preference" + SQL (2.4ms) CREATE TEMPORARY TABLE "altered_preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.6ms) DROP TABLE "preferences" + SQL (0.6ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("altered_preferences") + SQL (0.3ms) DROP TABLE "altered_preferences" + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.7ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091016174634') +Migrating to CreateBillingIntegrations (20091017175558) + SQL (0.8ms) CREATE TABLE "billing_integrations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime)  + SQL (2.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091017175558') +Migrating to ChargeRefactoring (20091021133257) + SQL (1.0ms) ALTER TABLE "orders" ADD "completed_at" datetime + ChargeRefactoring::Order Load (1.0ms) SELECT "orders".* FROM "orders" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "completed_at" datetime, "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("checkouts") + SQL (0.6ms) DROP TABLE "checkouts" + SQL (0.6ms) CREATE TABLE "checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("altered_checkouts") + SQL (0.3ms) DROP TABLE "altered_checkouts" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal DEFAULT 0.0 NOT NULL, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.5ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) UPDATE "adjustments" SET type = secondary_type  + SQL (0.2ms) UPDATE "adjustments" SET type = 'CouponCredit' WHERE (type = 'Credit') + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.5ms) DROP TABLE "adjustments" + SQL (3.1ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091021133257') +Migrating to AddSomeIndexes (20091104151730) + SQL (0.1ms) PRAGMA index_list("taxons") + SQL (0.6ms) CREATE INDEX "index_taxons_on_permalink" ON "taxons" ("permalink") + SQL (0.1ms) PRAGMA index_list("taxons") + SQL (0.1ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.4ms) CREATE INDEX "index_taxons_on_parent_id" ON "taxons" ("parent_id") + SQL (0.3ms) PRAGMA index_list("taxons") + SQL (0.1ms) PRAGMA index_info('index_taxons_on_parent_id') + SQL (0.1ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.4ms) CREATE INDEX "index_taxons_on_taxonomy_id" ON "taxons" ("taxonomy_id") + SQL (0.1ms) PRAGMA index_list("assets") + SQL (0.5ms) CREATE INDEX "index_assets_on_viewable_id" ON "assets" ("viewable_id") + SQL (0.2ms) PRAGMA index_list("assets") + SQL (0.1ms) PRAGMA index_info('index_assets_on_viewable_id') + SQL (0.4ms) CREATE INDEX "index_assets_on_viewable_type_and_type" ON "assets" ("viewable_type", "type") + SQL (0.1ms) PRAGMA index_list("product_properties") + SQL (0.4ms) CREATE INDEX "index_product_properties_on_product_id" ON "product_properties" ("product_id") + SQL (0.2ms) PRAGMA index_list("option_values_variants") + SQL (0.3ms) PRAGMA index_info('index_option_values_variants_on_variant_id') + SQL (0.4ms) CREATE INDEX "index_option_values_variants_on_variant_id_and_option_value_id" ON "option_values_variants" ("variant_id", "option_value_id") + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091104151730') +Migrating to CheckoutStateMachine (20091126190904) + SQL (0.8ms) ALTER TABLE "checkouts" ADD "state" varchar(255) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091126190904') +Migrating to StateForShipments (20091209153045) + SQL (0.8ms) ALTER TABLE "shipments" ADD "state" varchar(255) + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.8ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091209153045') +Migrating to MakeStateEventsPolymorphic (20091209202200) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "stateful_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255)) + SQL (0.1ms) PRAGMA index_list("state_events") + SQL (0.5ms) DROP TABLE "state_events" + SQL (0.7ms) CREATE TABLE "state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "stateful_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_state_events") + SQL (0.3ms) DROP TABLE "altered_state_events" + SQL (2.8ms) ALTER TABLE "state_events" ADD "stateful_type" varchar(255) + SQL (0.2ms) UPDATE "state_events" SET "stateful_type" = 'Order'  + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091209202200') +Migrating to ShipAddressIdForCheckouts (20091211203813) + SQL (0.8ms) ALTER TABLE "checkouts" ADD "ship_address_id" integer + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091211203813') +Migrating to ShippingMethodIdForCheckouts (20091212161118) + SQL (0.9ms) ALTER TABLE "checkouts" ADD "shipping_method_id" integer + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091212161118') +Migrating to CreditcardLastFourDigits (20091213222815) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.6ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + CreditcardLastFourDigits::Creditcard Load (0.3ms) SELECT "creditcards".* FROM "creditcards" + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091213222815') +Migrating to PopulateLegacyShipmentState (20091214183826) + PopulateLegacyShipmentState::Shipment Load (0.4ms) SELECT "shipments".* FROM "shipments" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091214183826') +Migrating to AddCostPrice (20100105090147) + SQL (1.0ms) ALTER TABLE "variants" ADD "cost_price" decimal(8,2) DEFAULT NULL + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100105090147') +Migrating to ShipmentIdForInventoryUnits (20100105132138) + SQL (0.9ms) ALTER TABLE "inventory_units" ADD "shipment_id" integer + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.2ms) PRAGMA index_info('index_inventory_units_on_order_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.4ms) CREATE INDEX "index_inventory_units_on_shipment_id" ON "inventory_units" ("shipment_id") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Shipment Load (0.6ms) SELECT "shipments".* FROM "shipments" + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100105132138') +Migrating to CimFieldsForCreditcards (20100111205525) + SQL (1.1ms) ALTER TABLE "creditcards" ADD "gateway_customer_profile_id" varchar(255) + SQL (0.6ms) ALTER TABLE "creditcards" ADD "gateway_payment_profile_id" varchar(255) + SQL (9.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100111205525') +Migrating to CreateReturnAuthorizations (20100112151511) + SQL (6.1ms) CREATE TABLE "return_authorizations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" varchar(255), "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "order_id" integer, "reason" text, "state" varchar(255), "created_at" datetime, "updated_at" datetime) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100112151511') +Migrating to AddReturnAuthorizationToInventoryUnits (20100113090919) + SQL (4.2ms) ALTER TABLE "inventory_units" ADD "return_authorization_id" integer + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100113090919') +Migrating to CreateTrackers (20100113203104) + SQL (0.8ms) CREATE TABLE "trackers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "environment" varchar(255), "analytics_id" varchar(255), "active" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (2.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100113203104') +Migrating to CreditcardIdForCreditcardTxns (20100121160010) + SQL (1.1ms) ALTER TABLE "creditcard_txns" ADD "creditcard_id" integer + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100121160010') +Migrating to OriginalCreditcardTxnIdForCreditcardTxns (20100121183934) + SQL (1.1ms) ALTER TABLE "creditcard_txns" ADD "original_creditcard_txn_id" integer + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100121183934') +Migrating to AddTestModeToBillingIntegration (20100125145351) + SQL (1.1ms) ALTER TABLE "billing_integrations" ADD "test_mode" boolean DEFAULT 't' + SQL (0.5ms) ALTER TABLE "billing_integrations" ADD "server" varchar(255) DEFAULT 'test' + SQL (2.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100125145351') +Migrating to CreateProductsProductGroups (20100126103714) + SQL (1.0ms) CREATE TABLE "product_groups_products" ("product_id" integer, "product_group_id" integer)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100126103714') +Migrating to CreatePaymentMethods (20100209025806) + SQL (0.9ms) CREATE TABLE "payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100209025806') +Migrating to PolymorphicPayments (20100209144531) + SQL (0.6ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer, "type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.8ms) DROP TABLE "payments" + SQL (0.6ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (3.3ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer)  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (1.2ms) DROP TABLE "payments" + SQL (0.4ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL)  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.4ms) DROP TABLE "payments" + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.5ms) ALTER TABLE "payments" ADD "payable_type" varchar(255) + SQL (0.5ms) ALTER TABLE "payments" ADD "payment_method" varchar(255) + SQL (0.5ms) ALTER TABLE "payments" ADD "source_id" integer + SQL (0.5ms) ALTER TABLE "payments" ADD "source_type" varchar(255) + SQL (0.1ms) UPDATE payments SET payable_type = 'Order' + Creditcard Load (0.3ms) SELECT "creditcards".* FROM "creditcards" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.6ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100209144531') +Migrating to ChangePaymentsPaymentMethodToBelongsTo (20100213103131) + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "payment_method" varchar(255), "source_id" integer, "source_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.5ms) DROP TABLE "payments" + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.2ms) DROP TABLE "altered_payments" + SQL (0.5ms) ALTER TABLE "payments" ADD "payment_method_id" integer + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100213103131') +Migrating to AssignCreditcardTxnsToPayment (20100214212536) + SQL (0.9ms) ALTER TABLE "creditcard_txns" ADD "payment_id" integer + SQL (0.2ms) SELECT * FROM creditcard_txns + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "creditcard_payment_id" integer, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer) + SQL (0.1ms) PRAGMA index_list("creditcard_txns") + SQL (0.7ms) DROP TABLE "creditcard_txns" + SQL (0.6ms) CREATE TABLE "creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_creditcard_txns") + SQL (0.3ms) DROP TABLE "altered_creditcard_txns" + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100214212536') +Migrating to StiForTransactions (20100223170312) + SQL (0.9ms) ALTER TABLE "creditcard_txns" RENAME TO "transactions" + SQL (0.6ms) ALTER TABLE "transactions" ADD "type" varchar(255) + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_transactions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer, "type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("transactions") + SQL (0.6ms) DROP TABLE "transactions" + SQL (0.5ms) CREATE TABLE "transactions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "original_creditcard_txn_id" integer, "payment_id" integer, "type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_transactions") + SQL (0.3ms) DROP TABLE "altered_transactions" + SQL (2.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100223170312') +Migrating to DropBillingIntegrations (20100223183812) + SQL (0.7ms) DROP TABLE "billing_integrations" + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100223183812') +Migrating to DeletedAtForPaymentMethods (20100224153127) + SQL (0.8ms) ALTER TABLE "payment_methods" ADD "deleted_at" datetime DEFAULT NULL + SQL (2.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100224153127') +Migrating to AddAdjustmentsIndex (20100301163454) + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (1.9ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (3.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100301163454') +Migrating to FixByPopularity (20100306153445) + SQL (0.3ms) UPDATE "product_scopes" SET name='descend_by_popularity' WHERE (name='by_popularity') + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.7ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100306153445') +Migrating to AddAltTextToImages (20100317120946) + SQL (1.5ms) ALTER TABLE "assets" ADD "alt" text + SQL (1.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100317120946') +Migrating to AddDisplayToPaymentMethods (20100427121301) + SQL (1.6ms) ALTER TABLE "payment_methods" ADD "display" varchar(255) DEFAULT NULL + SQL (1.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100427121301') +Migrating to AddAddressesCheckoutsIndexes (20100504142133) + SQL (0.1ms) PRAGMA index_list("addresses") + SQL (0.6ms) CREATE INDEX "index_addresses_on_firstname" ON "addresses" ("firstname") + SQL (0.2ms) PRAGMA index_list("addresses") + SQL (0.2ms) PRAGMA index_info('index_addresses_on_firstname') + SQL (0.7ms) CREATE INDEX "index_addresses_on_lastname" ON "addresses" ("lastname") + SQL (0.1ms) PRAGMA index_list("checkouts") + SQL (0.4ms) CREATE INDEX "index_checkouts_on_order_id" ON "checkouts" ("order_id") + SQL (0.2ms) PRAGMA index_list("checkouts") + SQL (0.2ms) PRAGMA index_info('index_checkouts_on_order_id') + SQL (0.8ms) CREATE INDEX "index_checkouts_on_bill_address_id" ON "checkouts" ("bill_address_id") + SQL (2.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100504142133') +Migrating to AddIconToTaxons (20100506180619) + SQL (0.9ms) ALTER TABLE "taxons" ADD "icon_file_name" varchar(255) + SQL (0.6ms) ALTER TABLE "taxons" ADD "icon_content_type" varchar(255) + SQL (0.7ms) ALTER TABLE "taxons" ADD "icon_file_size" integer + SQL (0.7ms) ALTER TABLE "taxons" ADD "icon_updated_at" datetime + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100506180619') +Migrating to AddDescriptionToTaxons (20100506185838) + SQL (0.9ms) ALTER TABLE "taxons" ADD "description" text + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100506185838') +Migrating to IndexForShipmentsNumber (20100528155333) + SQL (0.1ms) PRAGMA index_list("shipments") + SQL (0.8ms) CREATE INDEX "index_shipments_on_number" ON "shipments" ("number") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100528155333') +Migrating to AddIndexOnUsersPersistenceToken (20100528185820) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.6ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100528185820') +Migrating to AddDefaultToTaxCategories (20100605152042) + SQL (1.0ms) ALTER TABLE "tax_categories" ADD "is_default" boolean DEFAULT 'f' + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100605152042') +Migrating to AddDisplayToShippingMethods (20100624110730) + SQL (0.8ms) ALTER TABLE "shipping_methods" ADD "display_on" varchar(255) DEFAULT NULL + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624110730') +Migrating to RenamePaymentMethodDisplay (20100624123336) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "display_on" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payment_methods") + SQL (0.9ms) DROP TABLE "payment_methods" + SQL (0.6ms) CREATE TABLE "payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "display_on" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_payment_methods") + SQL (0.3ms) DROP TABLE "altered_payment_methods" + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624123336') +Migrating to RenamePreferencesField (20100624175547) + SQL (0.8ms) CREATE TEMPORARY TABLE "altered_preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (1.5ms) DROP TABLE "preferences" + SQL (0.7ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("altered_preferences") + SQL (1.1ms) DROP TABLE "altered_preferences" + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624175547') +Migrating to AddGuestFlag (20100811163637) + SQL (0.9ms) ALTER TABLE "users" ADD "guest" boolean + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100811163637') +Migrating to DropOrderToken (20100811205836) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal DEFAULT 0.0 NOT NULL, "total" decimal DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "token" varchar(255), "adjustment_total" decimal DEFAULT 0.0 NOT NULL, "credit_total" decimal DEFAULT 0.0 NOT NULL, "completed_at" datetime) + SQL (0.2ms) PRAGMA index_list("orders") + SQL (0.2ms) PRAGMA index_info('index_orders_on_number') + SQL (0.1ms) PRAGMA index_list("altered_orders") + SQL (0.3ms) CREATE INDEX "temp_index_altered_orders_on_number" ON "altered_orders" ("number") + SQL (0.8ms) DROP TABLE "orders" + SQL (0.5ms) CREATE TABLE "orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal DEFAULT 0.0 NOT NULL, "total" decimal DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "adjustment_total" decimal DEFAULT 0.0 NOT NULL, "credit_total" decimal DEFAULT 0.0 NOT NULL, "completed_at" datetime) + SQL (0.2ms) PRAGMA index_list("altered_orders") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_orders_on_number') + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.3ms) CREATE INDEX "index_orders_on_number" ON "orders" ("number") + SQL (0.3ms) DROP TABLE "altered_orders" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100811205836') +Migrating to PaymentsStateAndAssignedToOrderOnly (20100812162326) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer) + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.8ms) DROP TABLE "payments" + SQL (0.7ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.2ms) DROP TABLE "altered_payments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer) + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.6ms) DROP TABLE "payments" + SQL (0.4ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "source_id" integer, "source_type" varchar(255), "payment_method_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (1.1ms) ALTER TABLE "payments" ADD "state" varchar(255) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100812162326') +Migrating to CreateAddressKeysForOrder (20100813023502) + SQL (0.9ms) ALTER TABLE "orders" ADD "bill_address_id" integer + SQL (0.6ms) ALTER TABLE "orders" ADD "ship_address_id" integer + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100813023502') +Migrating to PaymentTotalForOrders (20100813185745) + SQL (0.8ms) ALTER TABLE "orders" ADD "payment_total" decimal(8,2) DEFAULT 0.0 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100813185745') +Migrating to ShippingMethodIdForOrders (20100816212146) + SQL (0.9ms) ALTER TABLE "orders" ADD "shipping_method_id" integer + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100816212146') +Migrating to AddShipmentAndPaymentState (20100817152723) + SQL (1.1ms) ALTER TABLE "orders" ADD "shipment_state" varchar(255) + SQL (0.6ms) ALTER TABLE "orders" ADD "payment_state" varchar(255) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100817152723') +Migrating to RefactorAdjustments (20100819170125) + SQL (1.0ms) ALTER TABLE "adjustments" ADD "mandatory" boolean + SQL (0.6ms) ALTER TABLE "adjustments" ADD "frozen" boolean + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "adjustment_source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.7ms) DROP TABLE "adjustments" + SQL (0.6ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "adjustment_source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.6ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.3ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.5ms) DROP TABLE "adjustments" + SQL (0.4ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.5ms) ALTER TABLE "adjustments" ADD "originator_id" integer + SQL (0.5ms) ALTER TABLE "adjustments" ADD "originator_type" varchar(255) + SQL (0.7ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.2ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.4ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "altered_adjustments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.2ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.4ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.2ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.4ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100819170125') +Migrating to ResponseCodeAndAvsResponseForPayments (20100820135707) + SQL (0.7ms) ALTER TABLE "payments" ADD "response_code" varchar(255) + SQL (0.5ms) ALTER TABLE "payments" ADD "avs_response" varchar(255) + SQL (3.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100820135707') +Migrating to ChangeGuestFlagToAnonymous (20100901171814) + SQL (0.7ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean)  + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.2ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_persistence_token" ON "altered_users" ("persistence_token") + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.8ms) DROP TABLE "users" + SQL (0.8ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean)  + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.4ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (0.4ms) DROP TABLE "altered_users" + SQL (36.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100901171814') +Migrating to EmailForOrders (20100903203949) + SQL (0.9ms) ALTER TABLE "orders" ADD "email" varchar(255) + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100903203949') +Migrating to CreateMailMethods (20100923162011) + SQL (0.7ms) CREATE TABLE "mail_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "environment" varchar(255), "active" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100923162011') +Migrating to RenameFrozenToLocked (20100929151905) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "locked" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.2ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.6ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "locked" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.4ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.5ms) DROP TABLE "altered_adjustments" + SQL (2.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100929151905') +Migrating to MoveSpecialInstructionsToOrders (20101008190536) + SQL (0.9ms) ALTER TABLE "orders" ADD "special_instructions" text + SQL (0.3ms) update orders set special_instructions = (select special_instructions from checkouts where order_id = orders.id) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101008190536') +Migrating to CreateLogEntries (20101026184700) + SQL (0.8ms) CREATE TABLE "log_entries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "source_id" integer, "source_type" varchar(255), "details" text, "created_at" datetime, "updated_at" datetime)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184700') +Migrating to MigrateTransactionsToPaymentState (20101026184714) + Transaction Load (0.4ms) select * from transactions group by payment_id having count(payment_id) = 1 and txn_type = 1 + Transaction Load (0.2ms) select * from transactions where txn_type=4 + Transaction Load (0.2ms) select * from transactions where txn_type = 2 + Transaction Load (0.2ms) select * from transactions where txn_type = 3 + Transaction Load (0.2ms) select * from transactions where txn_type = 5 + SQL (2.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184714') +Migrating to DeleteInProgressOrders (20101026184746) + SQL (1.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) DELETE FROM "orders" WHERE ("orders"."state" = 'in_progress') + SQL (0.3ms) delete from adjustments where order_id not in (select id from orders) + SQL (0.2ms) delete from checkouts where order_id not in (select id from orders) + SQL (0.2ms) delete from shipments where order_id not in (select id from orders) + SQL (0.2ms) delete from payments where order_id not in (select id from orders) + SQL (0.2ms) delete from line_items where order_id not in (select id from orders) + SQL (0.2ms) delete from inventory_units where order_id not in (select id from orders) + SQL (1.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (5.0ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184746') +Migrating to MigrateCheckoutToOrders (20101026184808) + Order Load (0.4ms) SELECT "orders".* FROM "orders" WHERE ("orders"."id" >= 0) ORDER BY orders.id ASC LIMIT 1000 + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184808') +Migrating to MigrateAdjustments (20101026184833) + SQL (0.4ms) update adjustments set amount = 0.0 where amount is null + SQL (0.2ms) update adjustments set mandatory = 'true', locked = 'true' + SQL (6.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184833') +Migrating to RemoveShippedState (20101026184855) + Order Load (0.5ms) SELECT "orders".* FROM "orders" WHERE ("orders"."state" = 'shipped') + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184855') +Migrating to PreventNilPaymentTotal (20101026184916) + SQL (0.3ms) update orders set payment_total = 0.0 where payment_total is null + SQL (2.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184916') +Migrating to PreventNilEmail (20101026184932) + SQL (0.7ms) update orders set email = 'guest@example.com' where email is null + SQL (0.3ms) update orders set email = 'guest@example.com' where email = '' + SQL (2.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184932') +Migrating to GenerateAnonymousUsers (20101026184959) + Order Load (0.4ms) SELECT "orders".* FROM "orders" WHERE ("orders"."user_id" IS NULL) + SQL (14.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.6ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184959') +Migrating to UpdateOrderState (20101026185022) + Order Load (0.4ms) SELECT "orders".* FROM "orders" + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026185022') +Migrating to CleanupLegacyTables (20101026192225) + SQL (0.8ms) DROP TABLE "checkouts" + SQL (0.7ms) DROP TABLE "transactions" + SQL (0.6ms) DROP TABLE "open_id_authentication_associations" + SQL (0.4ms) DROP TABLE "open_id_authentication_nonces" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026192225') +Migrating to RemoveNumberAndCvvFromCredicard (20101028151745) + SQL (0.6ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.6ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.2ms) DROP TABLE "altered_creditcards" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.6ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101028151745') +Migrating to DropAnonymousFieldForUser (20101103212716) + SQL (0.6ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_persistence_token" ON "altered_users" ("persistence_token") + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.8ms) DROP TABLE "users" + SQL (0.6ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.4ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.6ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (0.4ms) DROP TABLE "altered_users" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101103212716') +Migrating to RenamedRmaCancelledState (20101111133551) + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + ReturnAuthorization Load (0.2ms) SELECT "return_authorizations".* FROM "return_authorizations" WHERE ("return_authorizations"."state" = 'cancelled') + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101111133551') +Migrating to FixProblematicIndexNames (20101117031806) + SQL (0.2ms) PRAGMA index_list("preferences") +Index name 'index_preferences_on_index_preferences_on_owner_and_attribute_and_preference' on table 'preferences' does not exist. Skipping. + SQL (0.2ms) PRAGMA index_list("preferences") + SQL (0.7ms) CREATE UNIQUE INDEX "ix_prefs_on_owner_attr_pref" ON "preferences" ("owner_id", "owner_type", "name", "group_id", "group_type") + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101117031806') + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" + SQL (2.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) PRAGMA index_list("addresses") + SQL (0.1ms) PRAGMA index_info('index_addresses_on_lastname') + SQL (0.1ms) PRAGMA index_info('index_addresses_on_firstname') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.2ms) PRAGMA index_list("assets") + SQL (0.4ms) PRAGMA index_info('index_assets_on_viewable_type_and_type') + SQL (0.1ms) PRAGMA index_info('index_assets_on_viewable_id') + SQL (0.1ms) PRAGMA index_list("calculators") + SQL (0.2ms) PRAGMA index_list("configurations") + SQL (0.2ms) PRAGMA index_info('index_configurations_on_name_and_type') + SQL (0.3ms) PRAGMA index_list("countries") + SQL (0.3ms) PRAGMA index_list("coupons") + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.1ms) PRAGMA index_list("gateways") + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_shipment_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_order_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.2ms) PRAGMA index_list("line_items") + SQL (0.1ms) PRAGMA index_info('index_line_items_on_variant_id') + SQL (0.1ms) PRAGMA index_info('index_line_items_on_order_id') + SQL (0.1ms) PRAGMA index_list("log_entries") + SQL (0.1ms) PRAGMA index_list("mail_methods") + SQL (0.1ms) PRAGMA index_list("option_types") + SQL (0.1ms) PRAGMA index_list("option_types_prototypes") + SQL (0.1ms) PRAGMA index_list("option_values") + SQL (0.2ms) PRAGMA index_list("option_values_variants") + SQL (0.1ms) PRAGMA index_info('index_option_values_variants_on_variant_id_and_option_value_id') + SQL (0.1ms) PRAGMA index_info('index_option_values_variants_on_variant_id') + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.1ms) PRAGMA index_info('index_orders_on_number') + SQL (0.1ms) PRAGMA index_list("payment_methods") + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.2ms) PRAGMA index_info('ix_prefs_on_owner_attr_pref') + SQL (0.1ms) PRAGMA index_list("product_groups") + SQL (0.1ms) PRAGMA index_info('index_product_groups_on_permalink') + SQL (0.1ms) PRAGMA index_info('index_product_groups_on_name') + SQL (0.1ms) PRAGMA index_list("product_groups_products") + SQL (0.1ms) PRAGMA index_list("product_option_types") + SQL (0.2ms) PRAGMA index_list("product_properties") + SQL (0.2ms) PRAGMA index_info('index_product_properties_on_product_id') + SQL (0.2ms) PRAGMA index_list("product_scopes") + SQL (0.1ms) PRAGMA index_info('index_product_scopes_on_product_group_id') + SQL (0.1ms) PRAGMA index_info('index_product_scopes_on_name') + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.1ms) PRAGMA index_info('index_products_on_permalink') + SQL (0.1ms) PRAGMA index_info('index_products_on_name') + SQL (0.1ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.1ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.2ms) PRAGMA index_list("products_taxons") + SQL (0.1ms) PRAGMA index_info('index_products_taxons_on_taxon_id') + SQL (0.1ms) PRAGMA index_info('index_products_taxons_on_product_id') + SQL (0.1ms) PRAGMA index_list("properties") + SQL (0.1ms) PRAGMA index_list("properties_prototypes") + SQL (0.1ms) PRAGMA index_list("prototypes") + SQL (0.1ms) PRAGMA index_list("question_categories") + SQL (0.1ms) PRAGMA index_list("questions") + SQL (0.1ms) PRAGMA index_list("return_authorizations") + SQL (0.1ms) PRAGMA index_list("roles") + SQL (0.2ms) PRAGMA index_list("roles_users") + SQL (0.1ms) PRAGMA index_info('index_roles_users_on_user_id') + SQL (0.1ms) PRAGMA index_info('index_roles_users_on_role_id') + SQL (0.1ms) PRAGMA index_list("shipments") + SQL (0.1ms) PRAGMA index_info('index_shipments_on_number') + SQL (0.1ms) PRAGMA index_list("shipping_categories") + SQL (0.1ms) PRAGMA index_list("shipping_methods") + SQL (0.1ms) PRAGMA index_list("state_events") + SQL (0.1ms) PRAGMA index_list("states") + SQL (0.2ms) PRAGMA index_list("tax_categories") + SQL (0.1ms) PRAGMA index_list("tax_rates") + SQL (0.1ms) PRAGMA index_list("taxonomies") + SQL (0.2ms) PRAGMA index_list("taxons") + SQL (0.1ms) PRAGMA index_info('index_taxons_on_taxonomy_id') + SQL (0.1ms) PRAGMA index_info('index_taxons_on_parent_id') + SQL (0.1ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.1ms) PRAGMA index_list("trackers") + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("variants") + SQL (0.1ms) PRAGMA index_info('index_variants_on_product_id') + SQL (0.1ms) PRAGMA index_list("zone_members") + SQL (0.1ms) PRAGMA index_list("zones") + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" diff --git a/spec/test_app/log/development.log b/spec/test_app/log/development.log new file mode 100644 index 0000000..94b81b0 --- /dev/null +++ b/spec/test_app/log/development.log @@ -0,0 +1,35 @@ + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' diff --git a/app/views/faqs/show.rjs b/spec/test_app/log/production.log similarity index 100% rename from app/views/faqs/show.rjs rename to spec/test_app/log/production.log diff --git a/spec/test_app/log/server.log b/spec/test_app/log/server.log new file mode 100644 index 0000000..e69de29 diff --git a/spec/test_app/log/test.log b/spec/test_app/log/test.log new file mode 100644 index 0000000..1177342 --- /dev/null +++ b/spec/test_app/log/test.log @@ -0,0 +1,3675 @@ + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) select sqlite_version(*) + SQL (29.6ms) CREATE TABLE "schema_migrations" ("version" varchar(255) NOT NULL)  + SQL (0.1ms) PRAGMA index_list("schema_migrations") + SQL (24.0ms) CREATE UNIQUE INDEX "unique_schema_migrations" ON "schema_migrations" ("version") + SQL (0.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) SELECT "schema_migrations"."version" FROM "schema_migrations" +Migrating to CreateQuestions (20090526213535) + SQL (0.7ms) CREATE TABLE "questions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "question_category_id" integer, "question" text, "answer" text, "position" integer, "created_at" datetime, "updated_at" datetime)  + SQL (0.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090526213535') +Migrating to CreateQuestionCategories (20090526213550) + SQL (0.7ms) CREATE TABLE "question_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime) + SQL (0.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090526213550') +Migrating to SpreeZeroNineZero (20090823005402) + SQL (0.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.9ms) CREATE TABLE "addresses" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "firstname" varchar(255), "lastname" varchar(255), "address1" varchar(255), "address2" varchar(255), "city" varchar(255), "state_id" integer, "zipcode" varchar(255), "country_id" integer, "phone" varchar(255), "created_at" datetime, "updated_at" datetime, "state_name" varchar(255), "alternative_phone" varchar(255)) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255)) + SQL (0.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.7ms) CREATE TABLE "assets" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "viewable_id" integer, "viewable_type" varchar(50), "attachment_content_type" varchar(255), "attachment_file_name" varchar(255), "attachment_size" integer, "position" integer, "type" varchar(75), "attachment_updated_at" datetime, "attachment_width" integer, "attachment_height" integer) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) CREATE TABLE "calculators" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "calculable_id" integer NOT NULL, "calculable_type" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "completed_at" datetime, "created_at" datetime, "updated_at" datetime) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "configurations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "type" varchar(50)) + SQL (0.2ms) PRAGMA index_list("configurations") + SQL (0.5ms) CREATE INDEX "index_configurations_on_name_and_type" ON "configurations" ("name", "type") + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "countries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "iso_name" varchar(255), "iso" varchar(255), "name" varchar(255), "iso3" varchar(255), "numcode" integer) + SQL (0.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.6ms) CREATE TABLE "coupons" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "code" varchar(255), "description" varchar(255), "usage_limit" integer, "combine" boolean, "expires_at" datetime, "created_at" datetime, "updated_at" datetime, "starts_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) CREATE TABLE "creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "creditcard_payment_id" integer, "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime) + SQL (1.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "display_number" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer) + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "gateway_configurations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "gateway_id" integer, "created_at" datetime, "updated_at" datetime) + SQL (0.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "gateway_option_values" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "gateway_configuration_id" integer, "gateway_option_id" integer, "value" text, "created_at" datetime, "updated_at" datetime) + SQL (0.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "gateway_options" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" text, "gateway_id" integer, "textarea" boolean DEFAULT 'f', "created_at" datetime, "updated_at" datetime) + SQL (1.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "gateways" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "clazz" varchar(255), "name" varchar(255), "description" text, "active" boolean, "created_at" datetime, "updated_at" datetime) + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "inventory_units" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "variant_id" integer, "order_id" integer, "state" varchar(255), "lock_version" integer DEFAULT 0, "created_at" datetime, "updated_at" datetime) + SQL (0.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "line_items" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "variant_id" integer, "quantity" integer NOT NULL, "price" decimal(8,2) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("line_items") + SQL (0.3ms) CREATE INDEX "index_line_items_on_order_id" ON "line_items" ("order_id") + SQL (0.3ms) PRAGMA index_list("line_items") + SQL (0.2ms) PRAGMA index_info('index_line_items_on_order_id') + SQL (0.8ms) CREATE INDEX "index_line_items_on_variant_id" ON "line_items" ("variant_id") + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "option_types" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100), "presentation" varchar(100), "created_at" datetime, "updated_at" datetime)  + SQL (2.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "option_types_prototypes" ("prototype_id" integer, "option_type_id" integer)  + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "option_values" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "option_type_id" integer, "name" varchar(255), "position" integer, "presentation" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) CREATE TABLE "option_values_variants" ("variant_id" integer, "option_value_id" integer)  + SQL (0.1ms) PRAGMA index_list("option_values_variants") + SQL (0.3ms) CREATE INDEX "index_option_values_variants_on_variant_id" ON "option_values_variants" ("variant_id") + SQL (0.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal(8,2) DEFAULT 0.0 NOT NULL, "total" decimal(8,2) DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "token" varchar(255), "adjustment_total" decimal(8,2) DEFAULT 0.0 NOT NULL, "credit_total" decimal(8,2) DEFAULT 0.0 NOT NULL)  + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.3ms) CREATE INDEX "index_orders_on_number" ON "orders" ("number") + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "creditcard_id" integer, "type" varchar(255))  + SQL (0.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.6ms) CREATE UNIQUE INDEX "index_preferences_on_owner_and_attribute_and_preference" ON "preferences" ("owner_id", "owner_type", "attribute", "group_id", "group_type") + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "product_option_types" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "option_type_id" integer, "position" integer, "created_at" datetime, "updated_at" datetime)  + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "product_properties" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "property_id" integer, "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "products" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) DEFAULT '' NOT NULL, "description" text, "created_at" datetime, "updated_at" datetime, "permalink" varchar(255), "available_on" datetime, "tax_category_id" integer, "shipping_category_id" integer, "deleted_at" datetime, "meta_description" varchar(255), "meta_keywords" varchar(255))  + SQL (0.1ms) PRAGMA index_list("products") + SQL (0.4ms) CREATE INDEX "index_products_on_available_on" ON "products" ("available_on") + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.3ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.5ms) CREATE INDEX "index_products_on_deleted_at" ON "products" ("deleted_at") + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.2ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.1ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.6ms) CREATE INDEX "index_products_on_name" ON "products" ("name") + SQL (0.3ms) PRAGMA index_list("products") + SQL (0.2ms) PRAGMA index_info('index_products_on_name') + SQL (0.1ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.2ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.4ms) CREATE INDEX "index_products_on_permalink" ON "products" ("permalink") + SQL (0.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "products_taxons" ("product_id" integer, "taxon_id" integer)  + SQL (0.1ms) PRAGMA index_list("products_taxons") + SQL (0.3ms) CREATE INDEX "index_products_taxons_on_product_id" ON "products_taxons" ("product_id") + SQL (0.2ms) PRAGMA index_list("products_taxons") + SQL (0.2ms) PRAGMA index_info('index_products_taxons_on_product_id') + SQL (0.4ms) CREATE INDEX "index_products_taxons_on_taxon_id" ON "products_taxons" ("taxon_id") + SQL (0.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "properties" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "presentation" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime) + SQL (0.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "properties_prototypes" ("prototype_id" integer, "property_id" integer) + SQL (0.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "prototypes" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime) + SQL (1.0ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "roles" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255)) + SQL (1.0ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) CREATE TABLE "roles_users" ("role_id" integer, "user_id" integer) + SQL (0.2ms) PRAGMA index_list("roles_users") + SQL (0.4ms) CREATE INDEX "index_roles_users_on_role_id" ON "roles_users" ("role_id") + SQL (0.2ms) PRAGMA index_list("roles_users") + SQL (0.2ms) PRAGMA index_info('index_roles_users_on_role_id') + SQL (0.4ms) CREATE INDEX "index_roles_users_on_user_id" ON "roles_users" ("user_id") + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "shipments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "shipping_method_id" integer, "tracking" varchar(255), "created_at" datetime, "updated_at" datetime, "number" varchar(255), "cost" decimal(8,2), "shipped_at" datetime, "address_id" integer)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "shipping_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "shipping_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255))  + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "states" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "abbr" varchar(255), "country_id" integer)  + SQL (0.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "tax_categories" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (2.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "tax_rates" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "amount" decimal(8,4), "created_at" datetime, "updated_at" datetime, "tax_category_id" integer)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "taxonomies" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime)  + SQL (1.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.8ms) CREATE TABLE "taxons" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "taxonomy_id" integer NOT NULL, "parent_id" integer, "position" integer DEFAULT 0, "name" varchar(255) NOT NULL, "created_at" datetime, "updated_at" datetime, "permalink" varchar(255))  + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.6ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "variants" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_id" integer, "sku" varchar(255) DEFAULT '' NOT NULL, "price" decimal(8,2) NOT NULL, "weight" decimal(8,2), "height" decimal(8,2), "width" decimal(8,2), "depth" decimal(8,2), "deleted_at" datetime, "is_master" boolean DEFAULT 'f')  + SQL (0.1ms) PRAGMA index_list("variants") + SQL (0.4ms) CREATE INDEX "index_variants_on_product_id" ON "variants" ("product_id") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) CREATE TABLE "zone_members" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "zone_id" integer, "zoneable_id" integer, "zoneable_type" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.5ms) CREATE TABLE "zones" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "description" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090823005402') +Migrating to CreateIndexesForInventoryUnits (20090904192342) + SQL (0.1ms) PRAGMA index_list("inventory_units") + SQL (0.6ms) CREATE INDEX "index_inventory_units_on_variant_id" ON "inventory_units" ("variant_id") + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.2ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.4ms) CREATE INDEX "index_inventory_units_on_order_id" ON "inventory_units" ("order_id") + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090904192342') +Migrating to AddCountOnHandToVariantsAndProducts (20090923100315) + SQL (0.9ms) ALTER TABLE "variants" ADD "count_on_hand" integer DEFAULT 0 NOT NULL + SQL (0.6ms) ALTER TABLE "products" ADD "count_on_hand" integer DEFAULT 0 NOT NULL + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Variant Load (0.2ms) SELECT "variants".* FROM "variants" + Product Load (0.2ms) SELECT "products".* FROM "products" + SQL (1.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20090923100315') +Migrating to ChangeTaxonsToNestedSet (20091007134354) + SQL (0.8ms) ALTER TABLE "taxons" ADD "lft" integer + SQL (0.5ms) ALTER TABLE "taxons" ADD "rgt" integer + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + Taxon Load (0.3ms) SELECT "taxons".* FROM "taxons" WHERE (parent_id IS NULL) ORDER BY position ASC + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.1ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091007134354') +Migrating to MoveToConfigurableGateways (20091008091614) + SQL (0.5ms) DROP TABLE "gateways" + SQL (0.7ms) DROP TABLE "gateway_options" + SQL (0.5ms) DROP TABLE "gateway_option_values" + SQL (0.5ms) DROP TABLE "gateway_configurations" + SQL (1.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.6ms) CREATE TABLE "gateways" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "server" varchar(255) DEFAULT 'test', "test_mode" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091008091614') +Migrating to ProductGroupsAndScopes (20091012120519) + SQL (0.8ms) CREATE TABLE "product_groups" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(255), "permalink" varchar(255), "order" varchar(255))  + SQL (0.4ms) CREATE TABLE "product_scopes" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "product_group_id" integer, "name" varchar(255), "arguments" text) + SQL (0.1ms) PRAGMA index_list("product_groups") + SQL (0.4ms) CREATE INDEX "index_product_groups_on_name" ON "product_groups" ("name") + SQL (0.2ms) PRAGMA index_list("product_groups") + SQL (0.6ms) PRAGMA index_info('index_product_groups_on_name') + SQL (0.4ms) CREATE INDEX "index_product_groups_on_permalink" ON "product_groups" ("permalink") + SQL (0.1ms) PRAGMA index_list("product_scopes") + SQL (0.4ms) CREATE INDEX "index_product_scopes_on_name" ON "product_scopes" ("name") + SQL (0.2ms) PRAGMA index_list("product_scopes") + SQL (0.2ms) PRAGMA index_info('index_product_scopes_on_name') + SQL (0.4ms) CREATE INDEX "index_product_scopes_on_product_group_id" ON "product_scopes" ("product_group_id") + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091012120519') +Migrating to AddOpenIdAuthenticationTables (20091015110842) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.7ms) CREATE TABLE "open_id_authentication_associations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "issued" integer, "lifetime" integer, "handle" varchar(255), "assoc_type" varchar(255), "server_url" blob, "secret" blob) + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) CREATE TABLE "open_id_authentication_nonces" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "timestamp" integer NOT NULL, "server_url" varchar(255), "salt" varchar(255) NOT NULL) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091015110842') +Migrating to AddOpenidFieldToUsers (20091015153048) + SQL (1.0ms) ALTER TABLE "users" ADD "openid_identifier" varchar(255) + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.5ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (2.0ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.7ms) DROP TABLE "users" + SQL (1.8ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.7ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (1.5ms) DROP TABLE "altered_users" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128) DEFAULT '' NOT NULL, "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.5ms) DROP TABLE "users" + SQL (0.6ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.3ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.3ms) DROP TABLE "altered_users" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128) DEFAULT '' NOT NULL, "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.4ms) DROP TABLE "users" + SQL (0.6ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.3ms) DROP TABLE "altered_users" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091015153048') +Migrating to ChangePreferenceValueType (20091016174634) + SQL (0.2ms) PRAGMA index_list("preferences") + SQL (0.2ms) PRAGMA index_info('index_preferences_on_owner_and_attribute_and_preference') + SQL (0.5ms) DROP INDEX "index_preferences_on_owner_and_attribute_and_preference" + SQL (0.7ms) CREATE TEMPORARY TABLE "altered_preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" varchar(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.6ms) DROP TABLE "preferences" + SQL (0.6ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "attribute" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("altered_preferences") + SQL (0.4ms) DROP TABLE "altered_preferences" + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091016174634') +Migrating to CreateBillingIntegrations (20091017175558) + SQL (1.0ms) CREATE TABLE "billing_integrations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime)  + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091017175558') +Migrating to ChargeRefactoring (20091021133257) + SQL (2.0ms) ALTER TABLE "orders" ADD "completed_at" datetime + ChargeRefactoring::Order Load (0.3ms) SELECT "orders".* FROM "orders" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "completed_at" datetime, "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("checkouts") + SQL (0.5ms) DROP TABLE "checkouts" + SQL (0.6ms) CREATE TABLE "checkouts" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "email" varchar(255), "ip_address" varchar(255), "special_instructions" text, "bill_address_id" integer, "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("altered_checkouts") + SQL (0.3ms) DROP TABLE "altered_checkouts" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal DEFAULT 0.0 NOT NULL, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.6ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (1.6ms) DROP TABLE "altered_adjustments" + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) UPDATE "adjustments" SET type = secondary_type  + SQL (0.2ms) UPDATE "adjustments" SET type = 'CouponCredit' WHERE (type = 'Credit') + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255), "secondary_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.5ms) DROP TABLE "adjustments" + SQL (0.4ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "adjustment_source_id" integer, "adjustment_source_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091021133257') +Migrating to AddSomeIndexes (20091104151730) + SQL (0.1ms) PRAGMA index_list("taxons") + SQL (0.6ms) CREATE INDEX "index_taxons_on_permalink" ON "taxons" ("permalink") + SQL (0.2ms) PRAGMA index_list("taxons") + SQL (0.1ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.4ms) CREATE INDEX "index_taxons_on_parent_id" ON "taxons" ("parent_id") + SQL (0.2ms) PRAGMA index_list("taxons") + SQL (0.2ms) PRAGMA index_info('index_taxons_on_parent_id') + SQL (0.2ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.4ms) CREATE INDEX "index_taxons_on_taxonomy_id" ON "taxons" ("taxonomy_id") + SQL (0.1ms) PRAGMA index_list("assets") + SQL (4.9ms) CREATE INDEX "index_assets_on_viewable_id" ON "assets" ("viewable_id") + SQL (0.2ms) PRAGMA index_list("assets") + SQL (0.2ms) PRAGMA index_info('index_assets_on_viewable_id') + SQL (0.4ms) CREATE INDEX "index_assets_on_viewable_type_and_type" ON "assets" ("viewable_type", "type") + SQL (0.1ms) PRAGMA index_list("product_properties") + SQL (0.5ms) CREATE INDEX "index_product_properties_on_product_id" ON "product_properties" ("product_id") + SQL (0.2ms) PRAGMA index_list("option_values_variants") + SQL (0.2ms) PRAGMA index_info('index_option_values_variants_on_variant_id') + SQL (0.4ms) CREATE INDEX "index_option_values_variants_on_variant_id_and_option_value_id" ON "option_values_variants" ("variant_id", "option_value_id") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091104151730') +Migrating to CheckoutStateMachine (20091126190904) + SQL (1.0ms) ALTER TABLE "checkouts" ADD "state" varchar(255) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091126190904') +Migrating to StateForShipments (20091209153045) + SQL (1.0ms) ALTER TABLE "shipments" ADD "state" varchar(255) + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091209153045') +Migrating to MakeStateEventsPolymorphic (20091209202200) + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "stateful_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255)) + SQL (0.7ms) PRAGMA index_list("state_events") + SQL (0.6ms) DROP TABLE "state_events" + SQL (0.6ms) CREATE TABLE "state_events" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "stateful_id" integer, "user_id" integer, "name" varchar(255), "created_at" datetime, "updated_at" datetime, "previous_state" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_state_events") + SQL (0.3ms) DROP TABLE "altered_state_events" + SQL (0.5ms) ALTER TABLE "state_events" ADD "stateful_type" varchar(255) + SQL (0.2ms) UPDATE "state_events" SET "stateful_type" = 'Order'  + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091209202200') +Migrating to ShipAddressIdForCheckouts (20091211203813) + SQL (0.8ms) ALTER TABLE "checkouts" ADD "ship_address_id" integer + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091211203813') +Migrating to ShippingMethodIdForCheckouts (20091212161118) + SQL (1.0ms) ALTER TABLE "checkouts" ADD "shipping_method_id" integer + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091212161118') +Migrating to CreditcardLastFourDigits (20091213222815) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.6ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.2ms) DROP TABLE "altered_creditcards" + CreditcardLastFourDigits::Creditcard Load (0.3ms) SELECT "creditcards".* FROM "creditcards" + SQL (2.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091213222815') +Migrating to PopulateLegacyShipmentState (20091214183826) + PopulateLegacyShipmentState::Shipment Load (0.4ms) SELECT "shipments".* FROM "shipments" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20091214183826') +Migrating to AddCostPrice (20100105090147) + SQL (1.0ms) ALTER TABLE "variants" ADD "cost_price" decimal(8,2) DEFAULT NULL + SQL (3.0ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100105090147') +Migrating to ShipmentIdForInventoryUnits (20100105132138) + SQL (0.9ms) ALTER TABLE "inventory_units" ADD "shipment_id" integer + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_order_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.6ms) CREATE INDEX "index_inventory_units_on_shipment_id" ON "inventory_units" ("shipment_id") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Shipment Load (0.3ms) SELECT "shipments".* FROM "shipments" + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100105132138') +Migrating to CimFieldsForCreditcards (20100111205525) + SQL (1.0ms) ALTER TABLE "creditcards" ADD "gateway_customer_profile_id" varchar(255) + SQL (1.3ms) ALTER TABLE "creditcards" ADD "gateway_payment_profile_id" varchar(255) + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100111205525') +Migrating to CreateReturnAuthorizations (20100112151511) + SQL (1.9ms) CREATE TABLE "return_authorizations" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" varchar(255), "amount" decimal(8,2) DEFAULT 0.0 NOT NULL, "order_id" integer, "reason" text, "state" varchar(255), "created_at" datetime, "updated_at" datetime) + SQL (1.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100112151511') +Migrating to AddReturnAuthorizationToInventoryUnits (20100113090919) + SQL (0.9ms) ALTER TABLE "inventory_units" ADD "return_authorization_id" integer + SQL (2.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100113090919') +Migrating to CreateTrackers (20100113203104) + SQL (1.3ms) CREATE TABLE "trackers" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "environment" varchar(255), "analytics_id" varchar(255), "active" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100113203104') +Migrating to CreditcardIdForCreditcardTxns (20100121160010) + SQL (0.9ms) ALTER TABLE "creditcard_txns" ADD "creditcard_id" integer + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100121160010') +Migrating to OriginalCreditcardTxnIdForCreditcardTxns (20100121183934) + SQL (1.0ms) ALTER TABLE "creditcard_txns" ADD "original_creditcard_txn_id" integer + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100121183934') +Migrating to AddTestModeToBillingIntegration (20100125145351) + SQL (1.2ms) ALTER TABLE "billing_integrations" ADD "test_mode" boolean DEFAULT 't' + SQL (0.9ms) ALTER TABLE "billing_integrations" ADD "server" varchar(255) DEFAULT 'test' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100125145351') +Migrating to CreateProductsProductGroups (20100126103714) + SQL (0.7ms) CREATE TABLE "product_groups_products" ("product_id" integer, "product_group_id" integer)  + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100126103714') +Migrating to CreatePaymentMethods (20100209025806) + SQL (0.8ms) CREATE TABLE "payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100209025806') +Migrating to PolymorphicPayments (20100209144531) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer, "type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.5ms) DROP TABLE "payments" + SQL (0.6ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "creditcard_id" integer)  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.6ms) DROP TABLE "payments" + SQL (0.4ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.4ms) DROP TABLE "altered_payments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL)  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.4ms) DROP TABLE "payments" + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.7ms) ALTER TABLE "payments" ADD "payable_type" varchar(255) + SQL (0.7ms) ALTER TABLE "payments" ADD "payment_method" varchar(255) + SQL (0.6ms) ALTER TABLE "payments" ADD "source_id" integer + SQL (0.5ms) ALTER TABLE "payments" ADD "source_type" varchar(255) + SQL (0.1ms) UPDATE payments SET payable_type = 'Order' + Creditcard Load (0.3ms) SELECT "creditcards".* FROM "creditcards" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "checkout_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.7ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100209144531') +Migrating to ChangePaymentsPaymentMethodToBelongsTo (20100213103131) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "payment_method" varchar(255), "source_id" integer, "source_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.6ms) DROP TABLE "payments" + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "payable_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.6ms) ALTER TABLE "payments" ADD "payment_method_id" integer + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100213103131') +Migrating to AssignCreditcardTxnsToPayment (20100214212536) + SQL (0.8ms) ALTER TABLE "creditcard_txns" ADD "payment_id" integer + SQL (0.2ms) SELECT * FROM creditcard_txns + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "creditcard_payment_id" integer, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer) + SQL (0.1ms) PRAGMA index_list("creditcard_txns") + SQL (0.7ms) DROP TABLE "creditcard_txns" + SQL (1.6ms) CREATE TABLE "creditcard_txns" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_creditcard_txns") + SQL (0.3ms) DROP TABLE "altered_creditcard_txns" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100214212536') +Migrating to StiForTransactions (20100223170312) + SQL (0.9ms) ALTER TABLE "creditcard_txns" RENAME TO "transactions" + SQL (0.6ms) ALTER TABLE "transactions" ADD "type" varchar(255) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_transactions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "creditcard_id" integer, "original_creditcard_txn_id" integer, "payment_id" integer, "type" varchar(255)) + SQL (0.1ms) PRAGMA index_list("transactions") + SQL (0.6ms) DROP TABLE "transactions" + SQL (0.5ms) CREATE TABLE "transactions" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "amount" decimal DEFAULT 0.0 NOT NULL, "txn_type" integer, "response_code" varchar(255), "avs_response" text, "cvv_response" text, "created_at" datetime, "updated_at" datetime, "original_creditcard_txn_id" integer, "payment_id" integer, "type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_transactions") + SQL (0.2ms) DROP TABLE "altered_transactions" + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100223170312') +Migrating to DropBillingIntegrations (20100223183812) + SQL (0.7ms) DROP TABLE "billing_integrations" + SQL (2.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100223183812') +Migrating to DeletedAtForPaymentMethods (20100224153127) + SQL (1.1ms) ALTER TABLE "payment_methods" ADD "deleted_at" datetime DEFAULT NULL + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100224153127') +Migrating to AddAdjustmentsIndex (20100301163454) + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.7ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100301163454') +Migrating to FixByPopularity (20100306153445) + SQL (0.3ms) UPDATE "product_scopes" SET name='descend_by_popularity' WHERE (name='by_popularity') + SQL (3.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100306153445') +Migrating to AddAltTextToImages (20100317120946) + SQL (1.0ms) ALTER TABLE "assets" ADD "alt" text + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100317120946') +Migrating to AddDisplayToPaymentMethods (20100427121301) + SQL (1.1ms) ALTER TABLE "payment_methods" ADD "display" varchar(255) DEFAULT NULL + SQL (2.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.5ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100427121301') +Migrating to AddAddressesCheckoutsIndexes (20100504142133) + SQL (0.1ms) PRAGMA index_list("addresses") + SQL (0.8ms) CREATE INDEX "index_addresses_on_firstname" ON "addresses" ("firstname") + SQL (0.2ms) PRAGMA index_list("addresses") + SQL (0.2ms) PRAGMA index_info('index_addresses_on_firstname') + SQL (0.4ms) CREATE INDEX "index_addresses_on_lastname" ON "addresses" ("lastname") + SQL (0.1ms) PRAGMA index_list("checkouts") + SQL (1.5ms) CREATE INDEX "index_checkouts_on_order_id" ON "checkouts" ("order_id") + SQL (0.2ms) PRAGMA index_list("checkouts") + SQL (0.2ms) PRAGMA index_info('index_checkouts_on_order_id') + SQL (0.6ms) CREATE INDEX "index_checkouts_on_bill_address_id" ON "checkouts" ("bill_address_id") + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100504142133') +Migrating to AddIconToTaxons (20100506180619) + SQL (0.9ms) ALTER TABLE "taxons" ADD "icon_file_name" varchar(255) + SQL (0.6ms) ALTER TABLE "taxons" ADD "icon_content_type" varchar(255) + SQL (0.7ms) ALTER TABLE "taxons" ADD "icon_file_size" integer + SQL (0.7ms) ALTER TABLE "taxons" ADD "icon_updated_at" datetime + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100506180619') +Migrating to AddDescriptionToTaxons (20100506185838) + SQL (1.9ms) ALTER TABLE "taxons" ADD "description" text + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100506185838') +Migrating to IndexForShipmentsNumber (20100528155333) + SQL (0.1ms) PRAGMA index_list("shipments") + SQL (0.5ms) CREATE INDEX "index_shipments_on_number" ON "shipments" ("number") + SQL (2.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100528155333') +Migrating to AddIndexOnUsersPersistenceToken (20100528185820) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.8ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (3.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100528185820') +Migrating to AddDefaultToTaxCategories (20100605152042) + SQL (0.9ms) ALTER TABLE "tax_categories" ADD "is_default" boolean DEFAULT 'f' + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100605152042') +Migrating to AddDisplayToShippingMethods (20100624110730) + SQL (0.9ms) ALTER TABLE "shipping_methods" ADD "display_on" varchar(255) DEFAULT NULL + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624110730') +Migrating to RenamePaymentMethodDisplay (20100624123336) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "display_on" varchar(255))  + SQL (0.1ms) PRAGMA index_list("payment_methods") + SQL (0.5ms) DROP TABLE "payment_methods" + SQL (1.0ms) CREATE TABLE "payment_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "type" varchar(255), "name" varchar(255), "description" text, "active" boolean DEFAULT 't', "environment" varchar(255) DEFAULT 'development', "created_at" datetime, "updated_at" datetime, "deleted_at" datetime, "display_on" varchar(255)) + SQL (0.1ms) PRAGMA index_list("altered_payment_methods") + SQL (0.3ms) DROP TABLE "altered_payment_methods" + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624123336') +Migrating to RenamePreferencesField (20100624175547) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime)  + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.6ms) DROP TABLE "preferences" + SQL (0.6ms) CREATE TABLE "preferences" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "name" varchar(100) NOT NULL, "owner_id" integer(30) NOT NULL, "owner_type" varchar(50) NOT NULL, "group_id" integer, "group_type" varchar(50), "value" text(255), "created_at" datetime, "updated_at" datetime) + SQL (0.1ms) PRAGMA index_list("altered_preferences") + SQL (0.3ms) DROP TABLE "altered_preferences" + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100624175547') +Migrating to AddGuestFlag (20100811163637) + SQL (0.9ms) ALTER TABLE "users" ADD "guest" boolean + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100811163637') +Migrating to DropOrderToken (20100811205836) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal DEFAULT 0.0 NOT NULL, "total" decimal DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "token" varchar(255), "adjustment_total" decimal DEFAULT 0.0 NOT NULL, "credit_total" decimal DEFAULT 0.0 NOT NULL, "completed_at" datetime) + SQL (0.2ms) PRAGMA index_list("orders") + SQL (0.1ms) PRAGMA index_info('index_orders_on_number') + SQL (0.1ms) PRAGMA index_list("altered_orders") + SQL (0.3ms) CREATE INDEX "temp_index_altered_orders_on_number" ON "altered_orders" ("number") + SQL (0.7ms) DROP TABLE "orders" + SQL (0.6ms) CREATE TABLE "orders" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "user_id" integer, "number" varchar(15), "item_total" decimal DEFAULT 0.0 NOT NULL, "total" decimal DEFAULT 0.0 NOT NULL, "created_at" datetime, "updated_at" datetime, "state" varchar(255), "adjustment_total" decimal DEFAULT 0.0 NOT NULL, "credit_total" decimal DEFAULT 0.0 NOT NULL, "completed_at" datetime) + SQL (0.2ms) PRAGMA index_list("altered_orders") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_orders_on_number') + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.3ms) CREATE INDEX "index_orders_on_number" ON "orders" ("number") + SQL (0.3ms) DROP TABLE "altered_orders" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100811205836') +Migrating to PaymentsStateAndAssignedToOrderOnly (20100812162326) + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer) + SQL (0.1ms) PRAGMA index_list("payments") + SQL (1.2ms) DROP TABLE "payments" + SQL (1.0ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer)  + SQL (0.1ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "payable_type" varchar(255), "source_id" integer, "source_type" varchar(255), "payment_method_id" integer) + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.6ms) DROP TABLE "payments" + SQL (0.5ms) CREATE TABLE "payments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "created_at" datetime, "updated_at" datetime, "amount" decimal DEFAULT 0.0 NOT NULL, "source_id" integer, "source_type" varchar(255), "payment_method_id" integer)  + SQL (0.2ms) PRAGMA index_list("altered_payments") + SQL (0.3ms) DROP TABLE "altered_payments" + SQL (0.5ms) ALTER TABLE "payments" ADD "state" varchar(255) + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100812162326') +Migrating to CreateAddressKeysForOrder (20100813023502) + SQL (0.8ms) ALTER TABLE "orders" ADD "bill_address_id" integer + SQL (0.8ms) ALTER TABLE "orders" ADD "ship_address_id" integer + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100813023502') +Migrating to PaymentTotalForOrders (20100813185745) + SQL (0.8ms) ALTER TABLE "orders" ADD "payment_total" decimal(8,2) DEFAULT 0.0 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100813185745') +Migrating to ShippingMethodIdForOrders (20100816212146) + SQL (0.9ms) ALTER TABLE "orders" ADD "shipping_method_id" integer + SQL (1.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100816212146') +Migrating to AddShipmentAndPaymentState (20100817152723) + SQL (0.9ms) ALTER TABLE "orders" ADD "shipment_state" varchar(255) + SQL (0.7ms) ALTER TABLE "orders" ADD "payment_state" varchar(255) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100817152723') +Migrating to RefactorAdjustments (20100819170125) + SQL (0.9ms) ALTER TABLE "adjustments" ADD "mandatory" boolean + SQL (1.3ms) ALTER TABLE "adjustments" ADD "frozen" boolean + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "adjustment_source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.8ms) DROP TABLE "adjustments" + SQL (0.6ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "adjustment_source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.2ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.4ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.4ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.5ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean)  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.5ms) ALTER TABLE "adjustments" ADD "originator_id" integer + SQL (0.5ms) ALTER TABLE "adjustments" ADD "originator_type" varchar(255) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "type" varchar(255), "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "description" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.2ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.5ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "position" integer, "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.4ms) DROP TABLE "adjustments" + SQL (0.4ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "frozen" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.3ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100819170125') +Migrating to ResponseCodeAndAvsResponseForPayments (20100820135707) + SQL (0.8ms) ALTER TABLE "payments" ADD "response_code" varchar(255) + SQL (0.6ms) ALTER TABLE "payments" ADD "avs_response" varchar(255) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100820135707') +Migrating to ChangeGuestFlagToAnonymous (20100901171814) + SQL (0.6ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean)  + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_persistence_token" ON "altered_users" ("persistence_token") + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (0.7ms) DROP TABLE "users" + SQL (0.7ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean)  + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.2ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.4ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (0.4ms) DROP TABLE "altered_users" + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100901171814') +Migrating to EmailForOrders (20100903203949) + SQL (1.2ms) ALTER TABLE "orders" ADD "email" varchar(255) + SQL (2.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100903203949') +Migrating to CreateMailMethods (20100923162011) + SQL (0.7ms) CREATE TABLE "mail_methods" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "environment" varchar(255), "active" boolean DEFAULT 't', "created_at" datetime, "updated_at" datetime) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100923162011') +Migrating to RenameFrozenToLocked (20100929151905) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "locked" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("altered_adjustments") + SQL (0.3ms) CREATE INDEX "temp_index_altered_adjustments_on_order_id" ON "altered_adjustments" ("order_id") + SQL (0.7ms) DROP TABLE "adjustments" + SQL (0.7ms) CREATE TABLE "adjustments" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "order_id" integer, "amount" decimal, "label" varchar(255), "created_at" datetime, "updated_at" datetime, "source_id" integer, "source_type" varchar(255), "mandatory" boolean, "locked" boolean, "originator_id" integer, "originator_type" varchar(255))  + SQL (0.2ms) PRAGMA index_list("altered_adjustments") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_adjustments_on_order_id') + SQL (0.1ms) PRAGMA index_list("adjustments") + SQL (0.4ms) CREATE INDEX "index_adjustments_on_order_id" ON "adjustments" ("order_id") + SQL (0.3ms) DROP TABLE "altered_adjustments" + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20100929151905') +Migrating to MoveSpecialInstructionsToOrders (20101008190536) + SQL (1.1ms) ALTER TABLE "orders" ADD "special_instructions" text + SQL (0.2ms) update orders set special_instructions = (select special_instructions from checkouts where order_id = orders.id) + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101008190536') +Migrating to CreateLogEntries (20101026184700) + SQL (0.8ms) CREATE TABLE "log_entries" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "source_id" integer, "source_type" varchar(255), "details" text, "created_at" datetime, "updated_at" datetime)  + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184700') +Migrating to MigrateTransactionsToPaymentState (20101026184714) + Transaction Load (0.4ms) select * from transactions group by payment_id having count(payment_id) = 1 and txn_type = 1 + Transaction Load (0.4ms) select * from transactions where txn_type=4 + Transaction Load (1.9ms) select * from transactions where txn_type = 2 + Transaction Load (0.2ms) select * from transactions where txn_type = 3 + Transaction Load (0.2ms) select * from transactions where txn_type = 5 + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184714') +Migrating to DeleteInProgressOrders (20101026184746) + SQL (1.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) DELETE FROM "orders" WHERE ("orders"."state" = 'in_progress') + SQL (0.2ms) delete from adjustments where order_id not in (select id from orders) + SQL (0.2ms) delete from checkouts where order_id not in (select id from orders) + SQL (0.2ms) delete from shipments where order_id not in (select id from orders) + SQL (0.4ms) delete from payments where order_id not in (select id from orders) + SQL (0.2ms) delete from line_items where order_id not in (select id from orders) + SQL (0.2ms) delete from inventory_units where order_id not in (select id from orders) + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184746') +Migrating to MigrateCheckoutToOrders (20101026184808) + Order Load (0.5ms) SELECT "orders".* FROM "orders" WHERE ("orders"."id" >= 0) ORDER BY orders.id ASC LIMIT 1000 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184808') +Migrating to MigrateAdjustments (20101026184833) + SQL (1.8ms) update adjustments set amount = 0.0 where amount is null + SQL (0.2ms) update adjustments set mandatory = 'true', locked = 'true' + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184833') +Migrating to RemoveShippedState (20101026184855) + Order Load (0.4ms) SELECT "orders".* FROM "orders" WHERE ("orders"."state" = 'shipped') + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184855') +Migrating to PreventNilPaymentTotal (20101026184916) + SQL (0.3ms) update orders set payment_total = 0.0 where payment_total is null + SQL (2.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184916') +Migrating to PreventNilEmail (20101026184932) + SQL (0.3ms) update orders set email = 'guest@example.com' where email is null + SQL (0.2ms) update orders set email = 'guest@example.com' where email = '' + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184932') +Migrating to GenerateAnonymousUsers (20101026184959) + Order Load (0.5ms) SELECT "orders".* FROM "orders" WHERE ("orders"."user_id" IS NULL) + SQL (2.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026184959') +Migrating to UpdateOrderState (20101026185022) + Order Load (0.4ms) SELECT "orders".* FROM "orders" + SQL (1.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026185022') +Migrating to CleanupLegacyTables (20101026192225) + SQL (0.8ms) DROP TABLE "checkouts" + SQL (0.7ms) DROP TABLE "transactions" + SQL (0.5ms) DROP TABLE "open_id_authentication_associations" + SQL (2.4ms) DROP TABLE "open_id_authentication_nonces" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101026192225') +Migrating to RemoveNumberAndCvvFromCredicard (20101028151745) + SQL (0.5ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "number" text, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.5ms) DROP TABLE "creditcards" + SQL (0.8ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + SQL (0.4ms) CREATE TEMPORARY TABLE "altered_creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "verification_value" text, "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255)) + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.6ms) DROP TABLE "creditcards" + SQL (0.5ms) CREATE TABLE "creditcards" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "month" varchar(255), "year" varchar(255), "cc_type" varchar(255), "last_digits" varchar(255), "first_name" varchar(255), "last_name" varchar(255), "created_at" datetime, "updated_at" datetime, "start_month" varchar(255), "start_year" varchar(255), "issue_number" varchar(255), "address_id" integer, "gateway_customer_profile_id" varchar(255), "gateway_payment_profile_id" varchar(255))  + SQL (0.1ms) PRAGMA index_list("altered_creditcards") + SQL (0.3ms) DROP TABLE "altered_creditcards" + SQL (2.0ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101028151745') +Migrating to DropAnonymousFieldForUser (20101103212716) + SQL (0.6ms) CREATE TEMPORARY TABLE "altered_users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255), "anonymous" boolean) + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.5ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.2ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("altered_users") + SQL (0.5ms) CREATE INDEX "temp_index_altered_users_on_persistence_token" ON "altered_users" ("persistence_token") + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.3ms) CREATE INDEX "temp_index_altered_users_on_openid_identifier" ON "altered_users" ("openid_identifier") + SQL (1.1ms) DROP TABLE "users" + SQL (1.1ms) CREATE TABLE "users" ("id" INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, "email" varchar(255), "crypted_password" varchar(128), "salt" varchar(128), "remember_token" varchar(255), "remember_token_expires_at" varchar(255), "created_at" datetime, "updated_at" datetime, "persistence_token" varchar(255), "single_access_token" varchar(255), "perishable_token" varchar(255), "login_count" integer DEFAULT 0 NOT NULL, "failed_login_count" integer DEFAULT 0 NOT NULL, "last_request_at" datetime, "current_login_at" datetime, "last_login_at" datetime, "current_login_ip" varchar(255), "last_login_ip" varchar(255), "login" varchar(255), "ship_address_id" integer, "bill_address_id" integer, "openid_identifier" varchar(255)) + SQL (0.2ms) PRAGMA index_list("altered_users") + SQL (0.2ms) PRAGMA index_info('temp_index_altered_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_info('temp_index_altered_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_list("users") + SQL (0.4ms) CREATE INDEX "index_users_on_openid_identifier" ON "users" ("openid_identifier") + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.4ms) CREATE INDEX "index_users_on_persistence_token" ON "users" ("persistence_token") + SQL (0.4ms) DROP TABLE "altered_users" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.4ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101103212716') +Migrating to RenamedRmaCancelledState (20101111133551) + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + ReturnAuthorization Load (0.2ms) SELECT "return_authorizations".* FROM "return_authorizations" WHERE ("return_authorizations"."state" = 'cancelled') + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.3ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101111133551') +Migrating to FixProblematicIndexNames (20101117031806) + SQL (0.1ms) PRAGMA index_list("preferences") +Index name 'index_preferences_on_index_preferences_on_owner_and_attribute_and_preference' on table 'preferences' does not exist. Skipping. + SQL (0.1ms) PRAGMA index_list("preferences") + SQL (0.7ms) CREATE UNIQUE INDEX "ix_prefs_on_owner_attr_pref" ON "preferences" ("owner_id", "owner_type", "name", "group_id", "group_type") + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (0.2ms) INSERT INTO "schema_migrations" ("version") VALUES ('20101117031806') + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (2.7ms) SELECT "schema_migrations"."version" FROM "schema_migrations" + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (0.2ms) PRAGMA index_list("addresses") + SQL (0.2ms) PRAGMA index_info('index_addresses_on_lastname') + SQL (0.1ms) PRAGMA index_info('index_addresses_on_firstname') + SQL (0.2ms) PRAGMA index_list("adjustments") + SQL (0.1ms) PRAGMA index_info('index_adjustments_on_order_id') + SQL (0.2ms) PRAGMA index_list("assets") + SQL (0.2ms) PRAGMA index_info('index_assets_on_viewable_type_and_type') + SQL (0.2ms) PRAGMA index_info('index_assets_on_viewable_id') + SQL (0.1ms) PRAGMA index_list("calculators") + SQL (0.1ms) PRAGMA index_list("configurations") + SQL (0.2ms) PRAGMA index_info('index_configurations_on_name_and_type') + SQL (0.1ms) PRAGMA index_list("countries") + SQL (0.1ms) PRAGMA index_list("coupons") + SQL (0.1ms) PRAGMA index_list("creditcards") + SQL (0.1ms) PRAGMA index_list("gateways") + SQL (0.2ms) PRAGMA index_list("inventory_units") + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_shipment_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_order_id') + SQL (0.1ms) PRAGMA index_info('index_inventory_units_on_variant_id') + SQL (0.2ms) PRAGMA index_list("line_items") + SQL (0.1ms) PRAGMA index_info('index_line_items_on_variant_id') + SQL (0.1ms) PRAGMA index_info('index_line_items_on_order_id') + SQL (0.1ms) PRAGMA index_list("log_entries") + SQL (0.1ms) PRAGMA index_list("mail_methods") + SQL (0.1ms) PRAGMA index_list("option_types") + SQL (0.1ms) PRAGMA index_list("option_types_prototypes") + SQL (0.1ms) PRAGMA index_list("option_values") + SQL (0.2ms) PRAGMA index_list("option_values_variants") + SQL (0.2ms) PRAGMA index_info('index_option_values_variants_on_variant_id_and_option_value_id') + SQL (0.2ms) PRAGMA index_info('index_option_values_variants_on_variant_id') + SQL (0.1ms) PRAGMA index_list("orders") + SQL (0.1ms) PRAGMA index_info('index_orders_on_number') + SQL (0.1ms) PRAGMA index_list("payment_methods") + SQL (0.1ms) PRAGMA index_list("payments") + SQL (0.2ms) PRAGMA index_list("preferences") + SQL (0.3ms) PRAGMA index_info('ix_prefs_on_owner_attr_pref') + SQL (0.2ms) PRAGMA index_list("product_groups") + SQL (0.1ms) PRAGMA index_info('index_product_groups_on_permalink') + SQL (0.1ms) PRAGMA index_info('index_product_groups_on_name') + SQL (0.1ms) PRAGMA index_list("product_groups_products") + SQL (0.1ms) PRAGMA index_list("product_option_types") + SQL (0.1ms) PRAGMA index_list("product_properties") + SQL (0.1ms) PRAGMA index_info('index_product_properties_on_product_id') + SQL (0.1ms) PRAGMA index_list("product_scopes") + SQL (0.1ms) PRAGMA index_info('index_product_scopes_on_product_group_id') + SQL (0.1ms) PRAGMA index_info('index_product_scopes_on_name') + SQL (0.2ms) PRAGMA index_list("products") + SQL (0.1ms) PRAGMA index_info('index_products_on_permalink') + SQL (0.1ms) PRAGMA index_info('index_products_on_name') + SQL (0.1ms) PRAGMA index_info('index_products_on_deleted_at') + SQL (0.1ms) PRAGMA index_info('index_products_on_available_on') + SQL (0.2ms) PRAGMA index_list("products_taxons") + SQL (0.1ms) PRAGMA index_info('index_products_taxons_on_taxon_id') + SQL (0.1ms) PRAGMA index_info('index_products_taxons_on_product_id') + SQL (0.1ms) PRAGMA index_list("properties") + SQL (0.1ms) PRAGMA index_list("properties_prototypes") + SQL (0.1ms) PRAGMA index_list("prototypes") + SQL (0.1ms) PRAGMA index_list("question_categories") + SQL (0.1ms) PRAGMA index_list("questions") + SQL (0.1ms) PRAGMA index_list("return_authorizations") + SQL (0.1ms) PRAGMA index_list("roles") + SQL (0.1ms) PRAGMA index_list("roles_users") + SQL (0.1ms) PRAGMA index_info('index_roles_users_on_user_id') + SQL (0.1ms) PRAGMA index_info('index_roles_users_on_role_id') + SQL (0.1ms) PRAGMA index_list("shipments") + SQL (0.1ms) PRAGMA index_info('index_shipments_on_number') + SQL (0.1ms) PRAGMA index_list("shipping_categories") + SQL (0.1ms) PRAGMA index_list("shipping_methods") + SQL (0.1ms) PRAGMA index_list("state_events") + SQL (0.1ms) PRAGMA index_list("states") + SQL (0.1ms) PRAGMA index_list("tax_categories") + SQL (0.1ms) PRAGMA index_list("tax_rates") + SQL (0.1ms) PRAGMA index_list("taxonomies") + SQL (0.2ms) PRAGMA index_list("taxons") + SQL (0.1ms) PRAGMA index_info('index_taxons_on_taxonomy_id') + SQL (0.1ms) PRAGMA index_info('index_taxons_on_parent_id') + SQL (0.1ms) PRAGMA index_info('index_taxons_on_permalink') + SQL (0.1ms) PRAGMA index_list("trackers") + SQL (0.2ms) PRAGMA index_list("users") + SQL (0.1ms) PRAGMA index_info('index_users_on_persistence_token') + SQL (0.1ms) PRAGMA index_info('index_users_on_openid_identifier') + SQL (0.1ms) PRAGMA index_list("variants") + SQL (0.1ms) PRAGMA index_info('index_variants_on_product_id') + SQL (0.1ms) PRAGMA index_list("zone_members") + SQL (0.1ms) PRAGMA index_list("zones") + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT "schema_migrations"."version" FROM "schema_migrations" + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.3ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + AppConfiguration Load (0.3ms) SELECT "configurations"."id" FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (0.5ms) INSERT INTO "configurations" ("created_at", "name", "type", "updated_at") VALUES ('2010-11-22 20:50:57.375758', 'Default configuration', 'AppConfiguration', '2010-11-22 20:50:57.375758') + Preference Load (0.4ms) SELECT "preferences".* FROM "preferences" WHERE ("preferences".owner_id = 1 AND "preferences".owner_type = 'Configuration') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.418228', 'foo', 1, '2010-11-22 20:50:58.418228') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:50:58.432221', 1, 'value for question', 1, '2010-11-22 20:50:58.432221') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.443573', 'foo', 1, '2010-11-22 20:50:58.443573') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:50:58.448474', 1, 'value for question', 1, '2010-11-22 20:50:58.448474') + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE ("question_categories"."id" = 1) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.461357', 'foo', 1, '2010-11-22 20:50:58.461357') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.495537', 'foo', 1, '2010-11-22 20:50:58.495537') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.510502', 'foo', 1, '2010-11-22 20:50:58.510502') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.524455', 'foo', 1, '2010-11-22 20:50:58.524455') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:50:58.529992', 1, 'value for question', 1, '2010-11-22 20:50:58.529992') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:50:58.534925', 2, 'value for question', 1, '2010-11-22 20:50:58.534925') + SQL (0.2ms) UPDATE "questions" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "questions" SET "position" = 2, "updated_at" = '2010-11-22 20:50:58.540340' WHERE ("questions"."id" = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.549611', 'value for name', 1, '2010-11-22 20:50:58.549611') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (1.1ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.695720', 'value for name', 1, '2010-11-22 20:50:58.695720') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE ("questions".question_category_id = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'test') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.720977', 'test', 1, '2010-11-22 20:50:58.720977') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.727687', 'value for name', 2, '2010-11-22 20:50:58.727687') + SQL (0.2ms) UPDATE "question_categories" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + QuestionCategory Load (0.4ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "question_categories" SET "position" = 2, "updated_at" = '2010-11-22 20:50:58.733619' WHERE ("question_categories"."id" = 1) + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:50:58.743788', 'value for name', 1, '2010-11-22 20:50:58.743788') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + SQL (4.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.6ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.213834', 'foo', 1, '2010-11-22 20:51:12.213834') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:51:12.233776', 1, 'value for question', 1, '2010-11-22 20:51:12.233776') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.244290', 'foo', 1, '2010-11-22 20:51:12.244290') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:51:12.249038', 1, 'value for question', 1, '2010-11-22 20:51:12.249038') + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE ("question_categories"."id" = 1) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.261560', 'foo', 1, '2010-11-22 20:51:12.261560') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.295066', 'foo', 1, '2010-11-22 20:51:12.295066') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.308867', 'foo', 1, '2010-11-22 20:51:12.308867') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.322691', 'foo', 1, '2010-11-22 20:51:12.322691') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:51:12.327618', 1, 'value for question', 1, '2010-11-22 20:51:12.327618') + Question Load (0.5ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:51:12.332831', 2, 'value for question', 1, '2010-11-22 20:51:12.332831') + SQL (0.2ms) UPDATE "questions" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "questions" SET "position" = 2, "updated_at" = '2010-11-22 20:51:12.338028' WHERE ("questions"."id" = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.347364', 'value for name', 1, '2010-11-22 20:51:12.347364') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.356039', 'value for name', 1, '2010-11-22 20:51:12.356039') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE ("questions".question_category_id = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'test') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (2.0ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.379206', 'test', 1, '2010-11-22 20:51:12.379206') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.524332', 'value for name', 2, '2010-11-22 20:51:12.524332') + SQL (0.2ms) UPDATE "question_categories" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "question_categories" SET "position" = 2, "updated_at" = '2010-11-22 20:51:12.529778' WHERE ("question_categories"."id" = 1) + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:51:12.539123', 'value for name', 1, '2010-11-22 20:51:12.539123') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + SQL (4.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (3.8ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (2.9ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.6ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.6ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.093789', 'foo', 1, '2010-11-22 20:53:56.093789') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:53:56.111482', 1, 'value for question', 1, '2010-11-22 20:53:56.111482') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.122013', 'foo', 1, '2010-11-22 20:53:56.122013') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:53:56.127002', 1, 'value for question', 1, '2010-11-22 20:53:56.127002') + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE ("question_categories"."id" = 1) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.139955', 'foo', 1, '2010-11-22 20:53:56.139955') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.173649', 'foo', 1, '2010-11-22 20:53:56.173649') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.187679', 'foo', 1, '2010-11-22 20:53:56.187679') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.203276', 'foo', 1, '2010-11-22 20:53:56.203276') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:53:56.208168', 1, 'value for question', 1, '2010-11-22 20:53:56.208168') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:53:56.213502', 2, 'value for question', 1, '2010-11-22 20:53:56.213502') + SQL (0.2ms) UPDATE "questions" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + Question Load (0.4ms) SELECT "questions".* FROM "questions" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "questions" SET "position" = 2, "updated_at" = '2010-11-22 20:53:56.218767' WHERE ("questions"."id" = 1) + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.370293', 'value for name', 1, '2010-11-22 20:53:56.370293') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.379458', 'value for name', 1, '2010-11-22 20:53:56.379458') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE ("questions".question_category_id = 1) + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'test') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.406891', 'test', 1, '2010-11-22 20:53:56.406891') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.413445', 'value for name', 2, '2010-11-22 20:53:56.413445') + SQL (0.2ms) UPDATE "question_categories" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "question_categories" SET "position" = 2, "updated_at" = '2010-11-22 20:53:56.418637' WHERE ("question_categories"."id" = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:53:56.428043', 'value for name', 1, '2010-11-22 20:53:56.428043') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (2.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.4ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (2.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.6ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.6ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (2.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.9ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.8ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 165ms (Views: 13.6ms | ActiveRecord: 23.7ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + +Completed in 5ms + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 168ms (Views: 13.5ms | ActiveRecord: 24.6ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + +Completed in 5ms + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.4ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (2.1ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (1.1ms) +Completed 200 OK in 167ms (Views: 13.7ms | ActiveRecord: 25.0ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + +Completed in 5ms + SQL (1.7ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.7ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 164ms (Views: 13.2ms | ActiveRecord: 23.8ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + +Completed in 5ms + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.5ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 166ms (Views: 13.2ms | ActiveRecord: 24.9ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} +Completed in 7ms + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (2.5ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 172ms (Views: 13.2ms | ActiveRecord: 24.0ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} +Completed in 6ms + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.8ms) +Completed 200 OK in 166ms (Views: 13.2ms | ActiveRecord: 22.5ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} +Completed in 6ms + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.3ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 165ms (Views: 13.4ms | ActiveRecord: 23.5ms) + Processing by FaqsController#show as HTML + Parameters: {"id"=>1} +Completed in 7ms + SQL (4.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 168ms (Views: 14.0ms | ActiveRecord: 23.2ms) + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (5.1ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.2ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.2ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + Processing by FaqsController#index as HTML +Rendered /home/josh/Playground/spree-faq/app/views/faqs/index.html.erb within layouts/spree_application (0.9ms) +Completed 200 OK in 172ms (Views: 13.3ms | ActiveRecord: 23.5ms) + SQL (4.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + MailMethod Load (0.3ms) SELECT "mail_methods".* FROM "mail_methods" WHERE ("mail_methods"."environment" = 'test') LIMIT 1 + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.5ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.4ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.4ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + SQL (1.3ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + Property Load (0.2ms) SELECT "properties".* FROM "properties" WHERE ("properties"."name" = 'brand') LIMIT 1 + SQL (1.2ms) SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + SQL (1.3ms)  SELECT name + FROM sqlite_master + WHERE type = 'table' AND NOT name = 'sqlite_sequence' + + AppConfiguration Load (0.4ms) SELECT "configurations".* FROM "configurations" WHERE ("configurations"."type" = 'AppConfiguration') AND ("configurations"."name" = 'Default configuration') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.5ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.610166', 'foo', 1, '2010-11-22 20:59:18.610166') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:59:18.627996', 1, 'value for question', 1, '2010-11-22 20:59:18.627996') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.639009', 'foo', 1, '2010-11-22 20:59:18.639009') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:59:18.644030', 1, 'value for question', 1, '2010-11-22 20:59:18.644030') + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE ("question_categories"."id" = 1) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.657110', 'foo', 1, '2010-11-22 20:59:18.657110') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.691921', 'foo', 1, '2010-11-22 20:59:18.691921') + QuestionCategory Load (0.4ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.707682', 'foo', 1, '2010-11-22 20:59:18.707682') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'foo') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.721783', 'foo', 1, '2010-11-22 20:59:18.721783') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:59:18.727169', 1, 'value for question', 1, '2010-11-22 20:59:18.727169') + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "questions" ("answer", "created_at", "position", "question", "question_category_id", "updated_at") VALUES ('value for answer', '2010-11-22 20:59:18.732898', 2, 'value for question', 1, '2010-11-22 20:59:18.732898') + SQL (0.2ms) UPDATE "questions" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + Question Load (0.3ms) SELECT "questions".* FROM "questions" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "questions" SET "position" = 2, "updated_at" = '2010-11-22 20:59:18.738437' WHERE ("questions"."id" = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.3ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.748093', 'value for name', 1, '2010-11-22 20:59:18.748093') + QuestionCategory Load (0.3ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.756895', 'value for name', 1, '2010-11-22 20:59:18.756895') + Question Load (0.2ms) SELECT "questions".* FROM "questions" WHERE ("questions".question_category_id = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" IS NULL) LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'test') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.3ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.780543', 'test', 1, '2010-11-22 20:59:18.780543') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.4ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.786953', 'value for name', 2, '2010-11-22 20:59:18.786953') + SQL (0.2ms) UPDATE "question_categories" SET position = (position - 1) WHERE (1 = 1 AND position > 1) + QuestionCategory Load (0.4ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1 AND id != 1) ORDER BY position DESC LIMIT 1 + SQL (0.2ms) UPDATE "question_categories" SET "position" = 2, "updated_at" = '2010-11-22 20:59:18.794062' WHERE ("question_categories"."id" = 1) + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories".* FROM "question_categories" WHERE (1 = 1) ORDER BY position DESC LIMIT 1 + SQL (0.4ms) INSERT INTO "question_categories" ("created_at", "name", "position", "updated_at") VALUES ('2010-11-22 20:59:18.802791', 'value for name', 1, '2010-11-22 20:59:18.802791') + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + QuestionCategory Load (0.2ms) SELECT "question_categories"."id" FROM "question_categories" WHERE ("question_categories"."name" = 'value for name') LIMIT 1 + Processing by FaqsController#index as HTML +Completed 200 OK in 15ms (Views: 12.7ms | ActiveRecord: 38.3ms) diff --git a/spec/test_app/public/404.html b/spec/test_app/public/404.html new file mode 100644 index 0000000..9a48320 --- /dev/null +++ b/spec/test_app/public/404.html @@ -0,0 +1,26 @@ + + + + The page you were looking for doesn't exist (404) + + + + + +
+

The page you were looking for doesn't exist.

+

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

+
+ + diff --git a/spec/test_app/public/422.html b/spec/test_app/public/422.html new file mode 100644 index 0000000..83660ab --- /dev/null +++ b/spec/test_app/public/422.html @@ -0,0 +1,26 @@ + + + + The change you wanted was rejected (422) + + + + + +
+

The change you wanted was rejected.

+

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

+
+ + diff --git a/spec/test_app/public/500.html b/spec/test_app/public/500.html new file mode 100644 index 0000000..b80307f --- /dev/null +++ b/spec/test_app/public/500.html @@ -0,0 +1,26 @@ + + + + We're sorry, but something went wrong (500) + + + + + +
+

We're sorry, but something went wrong.

+

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

+
+ + diff --git a/spec/test_app/public/favicon.ico b/spec/test_app/public/favicon.ico new file mode 100644 index 0000000..e69de29 diff --git a/spec/test_app/public/images/add-to-cart.png b/spec/test_app/public/images/add-to-cart.png new file mode 100644 index 0000000000000000000000000000000000000000..4cccc77379146e779773477259eeb42693f55805 GIT binary patch literal 1157 zcmV;01bX|4P)RCwCdR$pjaRT%%y&25t1+$NVc zOa?Oa=gA^6Y;igpv04s}k1 z#tjt_ZKm^S)80@z*50%|X__=ilY9M6w6#emY-k_6a5(3D=R4o;`+qJm3xG7Kw{VxNEo&uO zjkN|A^GQ`rP5Q}t=F{)KXYAg+E9R`Nr3;i&tHp9<^-N35K`xhzu4AW6k-_gC9dQd= zgYncPwD}IhO!_+fJaZA6L=U9$i&1_(!1D5PG?AE7(&;p{TCGw(pARs)AP7+BtYyoW zSNEAr27dVQC-^4&I?UxLG}?E7$8kScc@dJ?8AxO%(f>p#1Hg(HTS})DO-qF4=jR8J zw5qX!fDx0)q#&1MHe13RM}n!;5~N#_&|uyUJuL$zMyJ&W_tkd52Unkm>C{yy2QZ9i zGMNOMAPib8mJlK2C?O!}x-o?Fv0|~PB3Cq1ki8ZqOSMi`~m{pWUgVtafFclo-J1E z15M^_z12x~zycC9JMM;B>(&F|C(ndRm0StXck+}MwV$l1sll|&$AAzOg$6i6A~-AP zHOa(rVFV50W#+ypDiXvwQZ3pPPjfTfwX@Z?)+%mQJOihOCK~D+gt@*HlHuFV|&XhYpvo|0L4NvS}3f@O^uC!u8>607F$|M zE9iUbaM)=+m-h-bA(qSLN`dFAc)+voHo^?8=1?V3ru?FgI1K2md4c_RxRbO)CnG<+E3kB-EUoL%@=W zf=vXT-{?(En+1#6Tsjv;aqOw!p`i`$K_%ghxB8E2HSf4i=*bybyl_#dCl|NURZ9|8;j Xd?CsVm8lY200000NkvXXu0mjflR7W& literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/active-tab.png b/spec/test_app/public/images/admin/bg/active-tab.png new file mode 100644 index 0000000000000000000000000000000000000000..80246340ba69500c3af4aba23c6c331150f2d76a GIT binary patch literal 218 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{T!3HEx%~ItDQY^(zo*^7SP{WbZ0pxQQctjR6 zFmQbUVMeDlCNqG7G9|7NCBgY=CFO}lsSJ)O`AMk?Zka`?<@rU~#R|^BCTyE7F950& z1*vl`N=+=u%+FH@$;?e|6H_V+Po~-c6`6UuIEGZ*s_ERw%b>t>_|lm@r?ThFQ1Eg!XY<}BldN}0 uEupQ@HgM}E=e+g&vj6`)_chzVD!~vJW~Tcx>ElzN2@IaDelF{r5}E)hA22@v literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/admin_tab_selected_back.png b/spec/test_app/public/images/admin/bg/admin_tab_selected_back.png new file mode 100644 index 0000000000000000000000000000000000000000..ed63dc2c5627ccd27e68dad41e3039cd316bdd3f GIT binary patch literal 142 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{M!2~3ezCWG-q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6&ZNCIEGZ*O1cpLt?i{fGxO#D|NlSyV$UPh@!y!iQ0uq- o4Bo>$0hTP%vm*nn8JKt&_!JyhJ8e-`0qSM&boFyt=akR{04jqklmGw# literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/content-back-blue.png b/spec/test_app/public/images/admin/bg/content-back-blue.png new file mode 100644 index 0000000000000000000000000000000000000000..140aa48cac958fa1f5c584a9ac87bc16eafa362b GIT binary patch literal 259 zcmV+e0sQ`nP)ulMv^zWdv7ecZ=5DyPwz zokQZ5rbllmlgMG6T>(MEZ>6Opa!z7I{x10xw-2$H5D_V^z)3T;y{zQWSWu9xqUsC> zHKMY#$-MfalqnCwKo24f2pbd)(BoBi$u6R9c+S0rb*(-E3;?*PhDvCAE6@M{002ov JPDHLkV1g5;Xhr}4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/content-back-green.png b/spec/test_app/public/images/admin/bg/content-back-green.png new file mode 100644 index 0000000000000000000000000000000000000000..394070ff3513a3c8e63a93b638247240d8c756d6 GIT binary patch literal 238 zcmeAS@N?(olHy`uVBq!ia0y~yU~>Sn89A7MBXBl9IAGK*2di9@kP07yJJE|Y%au-Nf)x^-V)3C?KDi^|&jxl|(aQ-U?mmn}a% zl&1XpcKOQhLhV;lw*_sD8#s-Fr0#c2{rhdP7k}XTe~pi#IHvkuGkovsqju~5tKhKW l5Z}d79TyL+{N>%i$S`MqPL^3{kUr3D44$rjF6*2UngB4BT?7CC literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/content-back.png b/spec/test_app/public/images/admin/bg/content-back.png new file mode 100644 index 0000000000000000000000000000000000000000..eb44aced3fbccb964af909ead573206386180985 GIT binary patch literal 181 zcmeAS@N?(olHy`uVBq!ia0y~yU~>Sn89A7MBy5$pZ(IXu^mO%eS?83{1OUU@LSz5{ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/flash-error.png b/spec/test_app/public/images/admin/bg/flash-error.png new file mode 100644 index 0000000000000000000000000000000000000000..486cdc44a7d83e28c1bffb6e2619d3b5f0c59c92 GIT binary patch literal 1784 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/green-stripes.png b/spec/test_app/public/images/admin/bg/green-stripes.png new file mode 100644 index 0000000000000000000000000000000000000000..6459eb656f121f0c7b14b061553c526d20f6774a GIT binary patch literal 199 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJ(ik&<|IDnvrBc%h#=PdAuEM{Qf z76M_$OLy!300l)$Tq8=Hi&7IyGV}8kLNaqx8I1IeO!N&bnfm-c02Ro96a?p|m6RtI zr7}3C}1?J0XJ#hl9^%zT#N^#A|=+vlxzXHGG3aErBl t^=hKH!eY%7lh&SHRVJ+gObkps3|_C*Hr0e(dkZvy!PC{xWt~$(69Dp-FB1R& literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/grid_header_back_green.png b/spec/test_app/public/images/admin/bg/grid_header_back_green.png new file mode 100644 index 0000000000000000000000000000000000000000..51694deb7ec25b5a484b79fc4c247843e26a0d1e GIT binary patch literal 169 zcmeAS@N?(olHy`uVBq!ia0vp^av;pX1SGcvS$+jlk|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*D5XyggkULn>}1?fF(J&78|1%zT!CoB8m6#TT#s|8Gxd;JLbC zS>mJL|LaXoUpV>VV#bo>i2w4s&M&4oHN33K5L@NE`IfBjb?5yROdJLbx1Y!#YyN!r QI?z}KPgg&ebxsLQ0J)eyng9R* literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/header-bg.png b/spec/test_app/public/images/admin/bg/header-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..2b70cbb655a2c4b2708c5b07d79b57a53fd40fef GIT binary patch literal 1235 zcmcIk&2G~`5Ox8fkW!&k;(|D=jKqm}ZRbx}*{Ry3ApsJqCK90%QaAP{wGw+Rd#gAR zst_l50}yA9aN!X^JOBr7ya3O@fpL;1X+d!6O5UH@@0*$ZcD%3mn)f%7w~~@1ZPaU( zeHho^OC_#CfBW;-O&G3(JN0$~+Vh0{3f9;B+S5>y)?sgbbM4!YlV34b>~=(p_r!<> zOxm`2m!YZ?un`XiAu6{rZ@yPAgRfMK>ogt_i@OSqVM^rslCc%})EY2>x~%Vbri>7h zkz_+@tF)FuIIO`2_MGO&uayj4mX5dpHx1VxcM^gO3Z_O!-I%pI|&1jg(PF;Xxm3#bObwI@a|xAkyL36EsSD;hmY2Q$H0JT7lyW zhkGdYOS}A7n6exPTD1A$sJ{s0g>&&hMjTNeYl?~&o`Gn9k(2{Q1rOSs4@-Z!5+i1w z0WG60`K&?(E5&-GH9f87+L})EJjrPXEBqPg9KFG9r#JqCo&`loPMy74z4g4xzWFaJ0gPOrtbFdH(Lc_IYOw6mJo7U}W8rK04xw9l~b^$ol<{xiQ> z)=(BumUvN@r>QTl@{xX$2qJP9v(a! o1K>uzvfWO+wGLlg>fQaBlCGQ5;}4&{6k$uM?=~wRcMf0v2EH;ffB*mh literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/header.png b/spec/test_app/public/images/admin/bg/header.png new file mode 100644 index 0000000000000000000000000000000000000000..5eba36744160a5f599bd37fc353ca40df7550118 GIT binary patch literal 132 zcmeAS@N?(olHy`uVBq!ia0vp^j6j^s!2~3)djIVQQr?~}jv*3LlYe}FFE7l@%q;cq z{FndsiW~p?@bK_>B>jI_Bw$$c=f6hU;!lQe9k(|N$j_d;<4D2IPQDpCAJ4N8X0|pL fX4X~*Vs?h3*@ku(--}EF8q476>gTe~DWM4fdBQ9- literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/header_bg.jpg b/spec/test_app/public/images/admin/bg/header_bg.jpg new file mode 100755 index 0000000000000000000000000000000000000000..fdb30738134789fd8e83fb597d31d317dcf8d962 GIT binary patch literal 5418 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 S^zJ!KHl6bDdDBW`y!!`Z6)w8~ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/menu-current.png b/spec/test_app/public/images/admin/bg/menu-current.png new file mode 100644 index 0000000000000000000000000000000000000000..5ad31697e62991ad200d70caba50f1f05539cfa4 GIT binary patch literal 715 zcmV;+0yO=JP)IJC(XvEGcAgkRruajK(T8l3Hn+`lC%QA!(b$ zoJsHTQ3RcC?f2mQg5-wVKEsFabN4(KQA!!U#=ndi03blb=br0zGVAxq2!IeFpL_3` zPjzRJ5di5E)^@+P)S5F4MMeOm7uKu#l==H=k`VyWg;jM+-`yqB0T6(~dg(kiSqlP? zUs$E~!nWs_CW}D;vI}cR^bN_VB^F4I*20#H~vXNpre00K~0 zrPe~b?~nxm;X-}Yd;90<6#z(|us$|t`>M-MQ2+rbtk2DPHi`lWMqyPN)lhtgAOHlQ zu+9$On03aZd!l3kKzd=FN}iwl`b0%tvH&2Qsgzo6e8{Zcw`_|z0EnKj^zYcvXku-o zr7FY$K>CEGFV)uCMDb2+z$Os@q9-ivVEjmGApOl-T>E0OBVs zZJ(7mow!nH&xFE!zz=}z!qUziy|$R23CD>AfcV0)BKDc#>+|)=a3oAL07Ms-mOgwn zw~;j>KZyo_G=H}>{O?okO}6}i!#V(@PgvTC1L?tXvSZXq2Y~bmOIzPsnJC`1VjR{1 zAbY~n4h^P8Vxtwc%y<0&NT0B@#*dAM@5ijY3|RnVPgvTJojke!QnCHQ3^8Q^5W#O# x`-S5-yPG{S0uX@0vZL|a7ax%k03m(}FaW`zx$-++ToM2P002ovPDHLkV1n(cMGgP} literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/red-stripes.gif b/spec/test_app/public/images/admin/bg/red-stripes.gif new file mode 100644 index 0000000000000000000000000000000000000000..9658243ba50f052da5fe4bebe205ade0884384de GIT binary patch literal 50 xcmZ?wbhEHbWMg1sXkcLY4+Qn~ia%KxKtKmXfMgh$IC&DLcka5L#KX#94FFTd3|jyI literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/red-stripes.png b/spec/test_app/public/images/admin/bg/red-stripes.png new file mode 100644 index 0000000000000000000000000000000000000000..aab5cfcd101d8d8b7d2b3ab9f547c710af3324e0 GIT binary patch literal 200 zcmeAS@N?(olHy`uVBq!ia0vp^Y#_`5A|IT2?*XJ(ik&<|IDnvrBc%h#=PdAuEM{Qf z76M_$OLy!300l)$Tq8=Hi&7IyGV}8kLNaqx8I1IeO!N&bnfm-c02Ro96a?p|m6RtI zr7}3Cn$9Tj2CbpxWRKH jgTe~DWM4fZNxjf literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/spree_50.png b/spec/test_app/public/images/admin/bg/spree_50.png new file mode 100644 index 0000000000000000000000000000000000000000..8d1ade475b25b65abea7bf9080fb421095ad8aac GIT binary patch literal 3349 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/subnav-divider.png b/spec/test_app/public/images/admin/bg/subnav-divider.png new file mode 100644 index 0000000000000000000000000000000000000000..79014f4de6315c236c2e51bd2320a4cb3c794658 GIT binary patch literal 206 zcmeAS@N?(olHy`uVBq!ia0vp^EFjFm1SHiab7}%9=3*z$5DpHG+YkL80J)q69+AZi z3|t>Tn9*sC$qb;NOo?kmNpOBzNqJ&XDuZK6ep0G}TV_#ed45rLv4V533EQU23xMiG zLF$}~QWHxu^Yau!GILWIjP#9+^$jfNN0xg66=-<6IEHY{OwPGcv^Dd!DH~gxRlcs< qvNKnC3=SM=V43l1&sK#sKp_StZ4MsqUm~$UJq(_%elF{r5}E+2**eq! literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/bg/subnav.png b/spec/test_app/public/images/admin/bg/subnav.png new file mode 100644 index 0000000000000000000000000000000000000000..f686445b4a9e5cfede37608a9cf9c315d51efc44 GIT binary patch literal 204 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/buttons/blue/right_01.png b/spec/test_app/public/images/admin/buttons/blue/right_01.png new file mode 100644 index 0000000000000000000000000000000000000000..f49cd294aa73efd1997ea6258a889070199a02fb GIT binary patch literal 416 zcmV;R0bl-!P)C5`W49re*5v8;q{wO4A-vSWO()b`E;OACD7oHAUT#lfB%u}JT_Kl z25Ct_AhuvQcj->%^^2GP0)=xya!kL0OiHk}rZR(&n0QV^&Wv!dfj|HJW1s~8{`a3j zQ%4hIRwl&DzyDDjv)tTVAj$x2AQj95`jZ(%@`DZh_2(Z|(;>_6zyGOhASkM+Y9Mue zOr2OpG4Lm~!|)HaWBJd2s>d?5z5I{L2Ht!5ohkI)5cP;^2C{sA1EN+^#X#mi-x=6{yZ|w$gAJ$1Wk23CaD06T3d3Sx>kI5<7S?Ys zNq5!nuRxc51BTtV9nd!7Cb%UWUmngP!*LgY_&Cs@3+NI60R{jNM96)h3W$FI0000< KMNUMnLSTYx9JZPO literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/buttons/drag-handle-green.png b/spec/test_app/public/images/admin/buttons/drag-handle-green.png new file mode 100644 index 0000000000000000000000000000000000000000..43f2d55a24f1d940299ca6b58fd64c8cfa362012 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^GC<75!3HFkH`xgRDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MNXbBjv*DdlD6bOSeuZLkdeN?_Ju{j|CN(iPwik{@;EbR zA>RqUWB>pEH@+Zjz|=fNiMe5+^QP9tg%(on&DMO3Ogs$ctr|6F0v!5*rZITB`njxg HN@xNApLH~{ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/buttons/green/left_01.png b/spec/test_app/public/images/admin/buttons/green/left_01.png new file mode 100644 index 0000000000000000000000000000000000000000..c23c7229830e9ddf49f1ce48d4696d158692b3fd GIT binary patch literal 717 zcmV;;0y6!HP)4j zXY=FSKa(n@6aY}N>d~9Wi`SRC~8OGu5WZfcdQ}+6d88=TiZG4YSjRs*s!}0RYa479RTHqT^Dps92>#}pyaS?+cs*$ zm;jU^o1 zet$i^KmD2Bn}7aA)$Duxe2Y6kL1C9eD=Gk06_0BidWtX()av+v)Me^ zr2E@>PA$#m(g5JEhuwTA@lQ=Vwssb5Nyi4jISRWpUBUR<;TG-B_f9)G;Re7t4!d9N z>~g@(m+lKU0G1}~@|<0D!d%)(d(r@4IXb)W1Qh_vHBbTo{)e#pGN>z+0HElw`xxV4 zL@V$BD7dqWx_Xs94^;zzV#6+bS$!M5O`k?OJOGL_S~!1NeI1SC`|w4(T1Tvh)l}vLEBP*=Mqb^!Zz5zSq00000NkvXXu0mjfj@&?m literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/buttons/green/right_01.png b/spec/test_app/public/images/admin/buttons/green/right_01.png new file mode 100644 index 0000000000000000000000000000000000000000..7faa92f14295b59d1ad103b8f1e71c8d611f092d GIT binary patch literal 412 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 N002ovPDHLkV1kB5C#nDd literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/buttons/right_01.png b/spec/test_app/public/images/admin/buttons/right_01.png new file mode 100644 index 0000000000000000000000000000000000000000..6593e136c4e83a3067da3ac2f9c178da3123e629 GIT binary patch literal 397 zcmV;80doF{P)B{;oD9e?45I5gQB{?w>pFs=HvqcoM5bvX6Nl@%A_xNQ zq9}G{St=Ob>qN3FBUvO^+i9ALwr#hN%867WYlUHmFgxhd2Jw9#n+>@d`9`m{fPC#E z)@+E@B*IIJ6JZbr;bQ+2kfv#@0C^IYh(Q>HK^TNV805c$DDoiYJ24{c8?N(Oc>Dnq_rG6aaLkGyqT<0Q|lfTxkH%wKNJB;Q(~x^%MX~ z0|2D~z(0y*SxNzbg;GlM(wIsEfNrHx*Zx-sz+yRncSW3U0ALxV0f0#ZfIpcuYAFEF zbu%tBVdiJ44sWbpsYBHI8G|N@Yh0*|^T~$@Z>&s|bmebpO z(!Y!kclV!S0iaEta|$7x)hP{T=a^F377GAvn(5-{=lM&30RZ`8dXBrzd|m(m002ov JPDHLkV1fn_tL*>) literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/16x16/1.png b/spec/test_app/public/images/admin/icons/16x16/1.png new file mode 100644 index 0000000000000000000000000000000000000000..c67d6f199dfa3155411141478852ab5e83e35937 GIT binary patch literal 942 zcmV;f15x~mP)vFLLmvbP+OB) z+G?A`&cvp1(m3g4CgYp;GjHCXcV;2(y_@&G_wK#t+;i^7=H`AzCpZ_t!~mL{8EDtD zFSOg%gBHs9FmfeL$Ze_^Jg20ZpLu-kd&~5Ih{5-Lh@Ijniom!JCAj&ZxsFd)<&SxL za0+trDwtrS*4mPeYCE@O8_(_UlPA7Ylq(0EmTdq8diLxrLbyl@x4ql2ZyZ_b+XsDQ z9tjn2eb7HZ69B?QZ5>E2e~2;h(C>}#*FCM4QxPo3L|htvq~$k{EDk(|#MnIgsX%do zaU8-9b__9Z2(dOW)DNtWzls%h;+9@<$0wRD5{FQL7-ZgDjvs^4w}cEqIh5>093%V< zjPlnZu`x7>4Q~O1I#5m@hQ&*d>pcIk(5sK!V~WMyb!8I0guFpXjQ}u$fatfn0yjg0 z&cF>~B~Wu&Z{WK4H5BweDk@^;$xVI=0W%O1%69FQ&PecKLPDK({J2A7Qw@VC1Fg$56;=wQ^L9dBstMWxIe%JGE zB?lu~$Gm+4HnEW;;MU|z-3FJcU*Vc@0Xica>3eMh7){+rOBA0IHk#$rJ=pT&_MT@@ zBA-(nNJQkl$00;&m$n`yp^-jWnS^YR8$lkor}m;!FP;>l$j8;|#iM&}dJQ>kH|GAJ z1Y#i45VNaq+C6MFD%Hi#JFMsAVHl9VF0H28 zTiCkmU{6wg$Ya)U2qwwk^}tnsDV8sPzG1A)_9Rl^q QxBvhE07*qoM6N<$f{Z4=ivR!s literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/16x16/10.png b/spec/test_app/public/images/admin/icons/16x16/10.png new file mode 100644 index 0000000000000000000000000000000000000000..0634e585a63320401aeafce434b4f795039731d1 GIT binary patch literal 895 zcmV-_1AzRAP)hQ5Ze<&P>ualhh>D zwwT&B6)m{p3WC(46&F+xQBiS4QQv$}M8O3W^iA|Zw1`rX`XIQ23R;&+>(U~oRdJ~` zt+v%9P1}sgY#G04f`7m}9GJ`8bMAM}_YG?cgAuN8>5XmhHeRk2%O{=9bxPoACP47{4;I`!f?V?hFw6Eta1rwS!}-AJv8x3N2{V9# zTYKS&d|t&10!w*baaon?d;9F1P#sW72h=RtYZLX1KrYMdO+pd55+iUmUW4fMFXxhH zQHwI=ik zS`WPz2VhA&%2U6?b*y|Q;z}{}7@dod^1ao>BSlDAPlWz<;Ngzp93q`0T~>p%)Af=k ze)YW21Le=fIh)Y^GUE>|&wx5A*UrUW(YHWt6*0Ro*g<2#OW;_r0@2QnTb!j0ba#9^ z?%uf%YSAowxti_3XPSrlbu>VYz?GF0ViW^m;A;agYX2F;-G%ju-mV9%xw#o?Qh{g8 zxC0eF_lds4Yms<=L>Uk$f3)iHDkXLR&#Ob}-^Y-;tha_l%DB_=hl}=OJ zHCRH9w|L^z?H-r7gel2V3rwOXra4@%e}4E_tNi}aEa!WMXM!;XX4${uf2_X(3;-<{ VIZOvMtr-9S002ovPDHLkV1l4xly3k4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/16x16/2.png b/spec/test_app/public/images/admin/icons/16x16/2.png new file mode 100644 index 0000000000000000000000000000000000000000..c88cbcd590634a3966d38ce5d5eac31bf66a6cce GIT binary patch literal 871 zcmV-t1DO1YP)eUh=_O_ppt`naSNJ7jRX_pu1QSB zB$Js*GFvaxZFQ#c=E;KBO;`VVzv{jJSx5VOxWV%rc*g?oS0^PTZ9lUzYq@CGWXIG+ z7AlEb%7izvIegVO+Vdo3=HP&XWmyp1V#fivoB<658DDZ>+sKqT^}hbjou-~00T|eaj&?X^7OZU6NtTEo({64;AoCW`h&kxCMo1F| z06PlwtiF!as@)&$AML9QUH>hlQ%NXgRT~6TKUR9V22!9CSVjeIZyfSL9bzhd_R;I! z9{d*B%=pq>7o=}(TREFnaccNz@%s2-g)7$9 zbN-TPD*{~|iwoLs0JCVp5Wymd1j!>R@J5Ldis_dx3V*{L@M?IY;0ung6+0h-Hxg99 zfcb}LrwS?d08U7jHUyvqk z)Fr8^o2rmAa-VaGx-v;hkBd?N&1b2DQWB9!eav+#KT?(yHDn;t3WE&HhBP<=hJ?&u z_YHMg_1=V00)Hd|U-Dvp<}g9_oX`nWglJySXoS+sYhX)qGnX8Qyfn1(24P7pel>Zj zyB1~%Ny4ai4vf4D!yhT-OonguCJg=j{(xh)iQaENP6ziLLUz(3e7WWAXcFR{D=CbP zl4t?GHW1I@^GGNYZ>RcuAG4;WM(CL|lqu7XRI0%<{l~W>`Qi~&(lI!Z%pg0{WKgV| zcngClKXn_)1#4QnT3c!gL?Ol+8()p-luo4((8_mIRaIWGp4H1EPw&F$e~X-xg;-b) zd2S7q&ASnmLbv+fwd^VI@dhu57$X=vt+ox*G~jSjsC4$cIwc^kW9iIPx-KF_7Sjd! xb>FAXYpH?WCM8$|=I%-l=D1h!KjM!70{|`cDa?8HJf{Ev002ovPDHLkV1g=8gJ0aTqG$>f~#ec$ijetDU<1#2OvKLhC)RL*6M zSW1h+Wkz*qut8Y37hQ%yPczVR74Xpt&&lXRkW6+1U+aPPn;7f_h6ER+ zKj+MnO`?Kytt04xOQMAms20Ej#ww^*#P0~4~9LMz82eV{hEu!&>bafFT3oD}B($mp#Bih^5Bxj8sZp!G7 hWV){7f9kIQ0|5U~H+%hQ5ZdUmQJQgCb6xt z(%Q6@mZ}8>seKf8RJ1RGxZnl_mp3026a=Nd_~LHe@Il-jd=YU&5NQ!3*3!DQ)>^cU zsoEw@>SUH=GVz;C{(&DHxXX9G^WAgrWxaiUaDw9nSm0463zf6Y#C|PnuN~7d$IL;j zl-X2eiQSWul&euocwwbgFa}tb1);#s=aFR`>cnh2pH6n3o$&FGa^)D26zG&$l{Cs) zvWdBS1BuNGgWSUbN!qR(=Cng)z5V?#ZJ^o5j>px^v9_Oc&>su|LE0^GG6)tSO_(rn zNgl?&>g-_eG?p2r`HM?yI_iAF2HnE3HDk5tpGD*_C6^Htf*)?NNFie<$kwqD2SoTnrqo}5^vj;dGbCb_dksi?{=V-p-H<6t^A|jqb4YeqUEY3w$ z?dFmS5wp{AU}_Qv2Z2++TrU^%g%e;U5nqhMt(2h(qhnYZ0K9zu4fivyz6#4$_s)89 zZR7_aXgK`d#>H{BlMP>im)~ii(J^ym%=c(Py{*xQ;qmwbE=#ZQ+eozIP-{6_{nT&d z1HH^7jt-faAIaeH4R74UljGFLQoV01>b}!N-Xg~uq`bqrnL`s!8S=X z@rUe2jERYB{&v$1Yc`wxo!On)+cU0jdGx@?+;iug?>pz*d)aU(49g@*f$*b_pNA2erV)#;0!Q~66E*ULZHYbY*LJ4axQiAYQiOT z>$Qm3Tma*6r8Uo9k!(1#Cb_@OjXy?hYDYoW)0|RSC_DnK479q~#bj2$uzPkRCS7&# zZ2-Qh0qP_mm;(m?qv*JX>+T3n_>J+i^A(f#PPFsDX-eL5Tl=d|awmCtp~c`)y&#lu~|0R^~H0K6HXIt#QDOsX;z z0NS?6I2v1v*SfmTU&Z$#_A2!G$oQnd&q>iSRZ%;XCRPh&0{PH|@Gc2q6*gv&f4?X? z|Ctr$%*!tBRh2`J(kl-w#R1k>>hHVF-i!WMZnTe$PtS{sl|;Bq*HIwCmfwxS60gatwbs3*lsbhKe2 zjfUoMz$@UC#1kG}%sdLLG6znzy7AkCH~2Fp@O?dSdn3?DWv{1p4m*K~Z58!>_vc_Y z3)sKag*Wqyz4$8_#EYSUJ;_W;Y`^wQ;QXNIis>uv!MrI%!!OeUr-S0&WJ0846F&wY z1i||I`;jYXX!g~d_0%_A{P)D zBxb=O8kZDXMFd5VVigy(ts)2wB=}G&1zYr`1*udKls@#q2gRD&LJ?eW0k;Qn(9lVo z7@K8AO=66RW1OsGZf3hPcV_O)@#ug)_}Bx7|1AG^HqH?}y?(qUS(cF%GF-*B>Kaqu zo3e6SgQjq&bFkHDn61&ME2@?L8M2gnRx$xW1k19ZyhF2+VekSqyGJo1e;l87$bY9R zFszoaQ-ULEy1s(G@MqV|H_OVToBg(;=A>!HB=(A4e*k74_^bp+bR%j-r0v!|ld&0yC=X3lx&wAPu&96_H<|Mqn4op7l`+92d5!GG|6MRG$GV~Ee zm{+{uQmO#a(j;GAnS@jWDgU)Eo{JI-^~mi zXbn;>__#%?EVk|T#d(%C89!A6LC$n84gAXUyUzU|<<^Jh00zt7M}SXcpsrHF^{9-b zq^*(^f%>Tw0W8ed0AGR;%#9M>6IYHk7SJ6l=x)2fm?eJMCUCM2@beq;zd~aL!7k-H(R%kTlG87}`)>0fk95qW&)57I-+olg|5__4q6;JJCfr^pIM{vmfojc%H$RUJ&+s=-N=2 zVxhtFo;x0hwzf7Hrimq0&R<-0OOEZlF^bl}Ys^_(iLDLga1|+NA4_1McLJ)K$JM5# z*ivHjbo7mEQZ!8$Uayz8MId1$QD0fs)X=cF002ovPDHLkV1mQvuTlU2 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/16x16/7.png b/spec/test_app/public/images/admin/icons/16x16/7.png new file mode 100644 index 0000000000000000000000000000000000000000..557dcd63825e91dda28e12b78bdf2637e1cd2ff8 GIT binary patch literal 910 zcmV;919AL`P)mQ!JQ;&C1VMmc8{o41fmJEk z4nu9?SEfo}>MlFCIBv>;zhyIVjjhexP3mcY<6xR5m_xR05=d*%^DEjklXd0veJA8k z_rPmS0G0xsFUd>DbrrF<+m9)s>K^w(vkC((;~`5G=cOwV3?VfAiV)JKLGwDLE#02nSQtpwU*Hd z%Av$J&zfBY?D!1-9Tp+&6ir!>#do@Zfd=sE4D6JV$I>bLS=y6duabao`Y{l`Lc5Uz ziAXj%kl!R{pKoeKBfxL1(4s)9v>cqsMVYcPeJd}t=aU4*ER9Wq&0OBB&q>}xIM};M zj#H2~4-hksr3GrFz7dw>8{#*XU)|S2W&Oh5)0m_BQLxp5L5L9^{Z4mal*lcB8ApOb z-arYY_gWBrInmAYX%q7kQ{Q+$y$G$i4li#LN!=2llVG3|=&GUPOd&oAJiiA7zUV|k zF1n*E&Hcd*hr`fR1#+nJ%d%YWw@Y6ghceI$Kix#Rh^$hb3OR|+l3rFe%D%pXjhYWe zrbfaIZjr^f@X%1kvEtmw?WHHm%ge5seZP9w|N05~(nDC53g#(=r@9gH;g7K_`ftyV z4xW`nmo6|DG6I>hEDHv`30si-fnB@XvOTPsQ`8+cI2U~}&E*}QA0NM-T$~;B<;e6H kIf4MrcAnz@82<_|02KN-Z==F+DgXcg07*qoM6N<$g7a^$fdBvi literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/16x16/8.png b/spec/test_app/public/images/admin/icons/16x16/8.png new file mode 100644 index 0000000000000000000000000000000000000000..4b7f308517e3b4f45eaa5596025954b4aa643325 GIT binary patch literal 910 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 P00000NkvXXu0mjf_RKr4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/10.png b/spec/test_app/public/images/admin/icons/32x32/10.png new file mode 100644 index 0000000000000000000000000000000000000000..0cd609a5180f959d454306f997b67e25b55a9f89 GIT binary patch literal 2174 zcmV-^2!Z#BP)(e zh3yz)8($#QZs-FfRpJt12oY7SHbrV_qqKQQiH>H44j{y<+Mk$|eI59EnrrmYPP4NCw%?_!E&S;mUO{O^aOiQi0X*+qig4Oy6l z7?^-19%9mwu(n~GAUb&VfAbaSq$Q!+kY=1v2i(}BEL5QRPRyP*yWtjJ@!_4Xy+%MVOV2#dwP?RrT znDqyrjm2VNtJR8!<(t43(?h@zM8!&YZ%|DZzv4>pz9#ox?~}QLL(oTjFj?5EXAEYagZO zkh$hPPu}sHL5xLy0Ap3)lUrys(7dLOh((zlumWr{6CSwwc0zFKBBsq}86 zyLAbyOkR%Dd-3U?KnaaPa}+)2ayg%1ATj{3nx%4+6^r9Vnb7B4JOGV&+^ctjm8|*gQOHAK?0B|@Q&kFfPC1Uq^sJ$1U)};xO zxpE7)kO7c|WgZaBbu|qv+e=;%%gAXrk3$;!7d_-}x7lnJ833q8U8-t%N+kty?>Qhs ziykgOr>YYb>jp8bLmBOc z?BQ`tED1@Hl;(PUc}EeJz6)vlG!szr^YD$NgG5Q*_y9mMBMsv#g4MYW{xM+o6G*N! zAxN{Hc_u&vG=%n%*<5j|4IS_(y@#Zvr*10{7WL!uN7d31qqvx(^{nR)~r_<1C;uG{9OU zH3&`Tn+#68&7$h-!1`n6u4+;urS)~4I!?)6py0IsA-M8;Ggkyto}sa5h|K?_ zN;j4R7)?aN5y|1UE|7rOVgPEw>}W}MS5Zl9xwxb-Z!ZsSDv%Vj;+L1=QujM^@B0M8 zX&MrxhN+dVfM`*Wh%Wjvl90~*o6(@}wvt-_J+B%wUT$@mb4>LC6X()1ZrMR9WG00{ z+Q+V&9wd(^W`Suc0%c`=Qd}$&9>@UT^ZELM^RwMdgso-^=Ev!*S>!Qf9OPk~+5wCl z{qG}=PR5<04%T(m>_nWQlx806IuN^2~~3B=t$ru6^{ z@=;R$@vu1;a9$s&nd&6H8>>**_6jB@X3*K$d0gOEs><0hED@<^&YT%&ZF%zXvg(FH zwR9E6Po6`J@=495_^I3~nb&v+o&S|o9iAHC&^iJ{eLk004)M&8_a?4UE>Q_qAGw5> zvj8{#{Ct&nHZBox>7@f7|x6W_KhWG7Xvu#F< z=-Ty;k)1ntHj_*`6O-wwWDLO%`(r}$8aw$NZEbC3FTC)hBMnVoZFFa;NCbVDyYdd^ zyDwtFdl&Hl^>#sq>RACtMJ+r{+u&(_hRjefK0Al*j%#PPwYI*@kEsypiKOZHd;qC` zG4=KJ%p$b`d&KM)j3X$jL%v=bAy&qksZ2#3O`}TD)clY)6 z#d*iY{|tat37Zw!Go#wtTH);3vkf^pIjv5otI6idE|D!Z8;#XsG#v6T_~(ZLLI3rM ziOF|&@7_Jq-`}sN23@v4{jXjIfdBh{$Nv^!0M=Drkrl=mM*si-07*qoM6N<$f}Qmq AiU0rr literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/11.png b/spec/test_app/public/images/admin/icons/32x32/11.png new file mode 100644 index 0000000000000000000000000000000000000000..39d6e6482eabda641254405375a611bbe50ff3f3 GIT binary patch literal 2327 zcmV+y3F!8TP)GeJM8s-Mq+`>j9b@{KHXZwjlf=ZtPE6_}6FRMiv`x~qK_*iv8ELf* zqF_)5H24@PMo}ZMD6lWs$KAWTx8K>j3#`br|Fttc!{Oe&_dDnNo$vd7kISj5ivQ-| z{wDymw6u(R5sSs*lMO{tpx5hRu~;4;`O;80x>$(`<73dJ11cwQidW*J*9?;GlV~h< z(Btu3h(@E(>2%;YZfK4iixw@4U&S$z(SmR|3{e!3o0I*Wpsf6&H)PILMJxD7AGnYc zqB=WgTWx3*fh&*O8;w5 z&^}dBR2ch@z~OI%O=*KM)(ur207nX91j;Yv!NnKCZG8w%$Nlrtd2ikLas1(aw{M*s z4hIcn!MnM8lna>hP$&eu&9Yw9TR!ac+hG}KK%R3Kto{ao4#P!3Rvlv^!jqA{zo(<33jZ!dDYUj|Q` zi(!&+lVFghIS;&L5@{wR-VO+%TY!;(86(IH9f0k#T3pN9j~gg)%~05GzdOvWV!b4F#S*N9m?TVeO^gQ$?8iv)xmVCl0!!DE1RLaHr$+kn>Jf^Yp5 z^Z^B&Z2*)2R?bG&J;2I6Btu9umP4Y8j*OFgV>7I-TDZ9>le05z`(;^9SvCZK znLfi|+ZvRn6zXpuf&Iod7)X{U09gJT;NkM&Re^rs%zHrH4&dmkK>Od=F4{Z23D|fP znDI?Ww3g_BoSV_OODh1O`ZV&;OtS-J?*OycXwOy=zz=W2=&py1t1vk$5X;yFV_NSsUa#+HiUk+| zlgYFW=~E`cc?f#1191L!sFI`9Xf#es0bno~ERv-AicaMqIBUU)T9{$MGsBx5qWjM&4E=N;HP8uP z0e*fG_-P~X#ixJ}v|0ZmaOLmXnhfGa;gd)sEnI~1M$bPW>a#$Rusj6-J($ahhGJd_ zLiDvlWTy|%tNap8%F_Wfm1`%BQanCKd81?-FzpNE>-&HwDu5>sXaFc;(6DnDc>Wr2 zEPOc@!e=1Twt^rm90I^Xg8aUS)0yYM-wCzaU816bU@r2om{8G#le6;Y0)o41l*Cybz(pB^4y=1D{x)%kz>Bu>gVbYfns5hBqfrEXjZ@ zkLeGLUE1cYCf-1s{a3YT#w;>%2IV2*ZK$7IL8ReDTZ#)PIjBs6qnsLzC0Nakpt*t9 zlxs0NHh^S!F|d-5ToBhn8fbFy+M$j}g>e8>LOY{MC?puHP{cR}# zTrSrIpQry*flh9mxC{fdz{e`w^%_kojr_Rec}l@_Pb~=EzaRL^cZqD2PudOv?>$Q4 z_Y*2miPX0ErQ!P0Q4Jp{4NxQ)Cwv(!z}zm^xrC!N0IOE5Qo6c2j|E7vc~%)BBp9WQwyWCu|_M6_gE$57vJlF0!hJ_R6B9W)O|&xP1QbjvYJtl4U@Q_Y;B; z=Y4zIrFZhC&)+^}#U7lg_y`_7C5=z_VZ1&Q(vnxSU1xkcnZY2oCW0j{1i$I zezXSNT`h6tl7SkNrCV{m(~0Kh=65-*9uGCd>~|W?Y?im`>+8?OqN;lH^xNvkyP!6| z2KDM2Q2n**RW%Y;|J{gruB-0%=c<=>Lv4B;>c=~vdb`f61B0qsU0wZ0(lM2#r$n%F z!X2eqwA=0HawkmOIJ5W>4zeEI-F5Ns_PZ}3dS(wK#S1>o0nR{9=M&4r1BmuCA=vO7 zoOPSf{FNG^8{PWmKrnt=eNQ6nl?a^o$T;^{_!jD;3UG&23xhj>iB?g!uPg}Tn+#L002ovPDHLkV1nsxcD(=q literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/2.png b/spec/test_app/public/images/admin/icons/32x32/2.png new file mode 100644 index 0000000000000000000000000000000000000000..9c6459c5a1dffe3f0ccd02f5fa04ccbd30ab231e GIT binary patch literal 2065 zcmV+s2=4cZP)CiUd*-5@4hvh3!uu{3(?zwS|C6BdA-6DnbU@ z#)+vNH;El@Nz*1xvEy;<%-G}ctZ&}Jxo_^&Z(M_bKmEbA&b;fpo$q{Sx$g<4Y2xE- zB0lCOv!Bt?(T_|pW(>oy`kJP};cy@j@IOow9XVBhpa^B74#_J(5F`|r9D;Vsk0;aq`%EO_+5z!TRIVMCAojr$bmwyKNMjwy`j36x}F*tm& zKtGH0%+NC;BfFy$H}3C3Hqd~L#+`+9CjC$@m%m>z;ZvBZeGHq;JL+;O*_z82uCZ8R zI?DhmvVi&A=k>HX168Nv2%z=i_YgkyG_(lm{2VQ=u_+f<2^&*rdK-23Q{d*7QQQ4R zG<@(9=A4@x0e_&E0@2HYvmD%OreQD;{B_D3MZ@q(xKBR={XPnmCffp10w)P`shf+7 zkI9?~2X*(5LDj(e=e~;SsWV6g>o%_o`ny$Ct;hzkoN|o%NGRB)hU*&r@1I4mrwjUa zvS43x26IGSt+*_GR=cdy|FI}oG9j#v-)E}eoj^8t0D9bT_@TLl10kATDB ze1rm&l)nZcPlI7jB?F+XSY+*xZ4B5IifinlF{zG*XJ)D7_Ci_b1=WOos{u3%4)>>| zyg?{OAeEIfS5YN|o6KN^#OW$M6%v!g;7^9cLE`3Xn7D}+NwQLtvB%<0n!Z@VDN4IP ztb{Bg$H&J$EjWEmW^x8X{5qrn2f!-rgFgm#cF{rcmE14qeML#L%`r7{2zc{RV4~Mz zNMx>vzYB?CN|2QuY;etdWF`inCk1(S=jSpin24phaO2ei|=d`L^3btpl>@wTQyq{ho0%?uA zaj&&~ArT)fb7%o*Z*MP7Pfzz{Xx95sr&T^vbGAb@-e<~k+{zrcGQ<1jah0#tO5k;x zPu?WLw$;G3`yi6D3GIA;{~+g35KFhPARjq$#erMzjP)Kremq`wzXgEq0ZXo5o%l_XHg5XXNvM>H zb0fq=ic^}gDNgem!6aqt+W`qB<#S}Ka{oQp(D{ADX5$zd8agHL2JT&U8%iXOo}Qj- zhuZh=t8Z+rR_f{yd+{}}dqbx80T%_6P_X&AXro%S3H@&nxp7K>J8uydik-&i`=I*Q zwF;w$xSj|jphH)1cnjsgXdM)gSI)wK*l;PGMV zr66UmXlVj9cZZapCqig$*Khv{-_||2I52SIz<~o_*L7Xx95H9<7Jw^Pt{C0j-PUz8 zI5@bxeS5=1C{p#<*3Wdn`(Pttf9XN;?b7Nz!7S)2#usQ;mi|f6kx9z#yA!}{KLKrx zqUCp&NO>DBT^?R|_E*n*X=G$%(dNvRmjVJ{2@eeR%31gG6DOV+o4jh6tVZTi=6k>V zvUz?F%)WYdl5@mx#Wp4PD20d08!3;lmYa^!Vnrrt#{ zHBXL{;S6seOLrmMc97&SyKE3kBr!bD|H`3`j_>jiO_QFyO~=0mP`;^JT3Q$*o)=zt z{$O+SeLvjNbnlL^TegCwQ~>F#$NDP;5Od4jWEwX{FQ2<`Vem&?T|XFRbdQaV6?w(Q ze+;1F#gRU%nwpvf%955yByz~-4?N%vglZL+$0HbqSjcCV(o4yksnpUyEEfCI(W6JF vCMPH9j?=C8O}5|usaFBu|NiUvp8^a3@&Hk3I`J4e00000NkvXXu0mjf=fvIY literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/3.png b/spec/test_app/public/images/admin/icons/32x32/3.png new file mode 100644 index 0000000000000000000000000000000000000000..9dc32ebc0917ad6794d236b6dc543fc47cc6d6a0 GIT binary patch literal 2203 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/4.png b/spec/test_app/public/images/admin/icons/32x32/4.png new file mode 100644 index 0000000000000000000000000000000000000000..dcdc53963e038e2952d1ee5db7987a09323d38fc GIT binary patch literal 2206 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 TWlx($00000NkvXXu0mjfGe0^_ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/6.png b/spec/test_app/public/images/admin/icons/32x32/6.png new file mode 100644 index 0000000000000000000000000000000000000000..06b22dd86fed385dba8857fada2191fa40da1921 GIT binary patch literal 2296 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/32x32/8.png b/spec/test_app/public/images/admin/icons/32x32/8.png new file mode 100644 index 0000000000000000000000000000000000000000..2dced96cb4711d33123f3812b6c731eede41c265 GIT binary patch literal 2154 zcmV-w2$lDVP)Q#Wf~JKw)aK!!2HJ>9RaB*^)R)@SmC}l+j~`8)rLfA2ZW)ckkj|>a>;mBR@LQ*_pj_@A+hiI-SluCzDAS33v1)Z5qm$Xz+ zFQl&-^>Ux0s-3}LaGb5x>-D$wiDIFxjg5_q1eUtkqEw1tNJ;rJ*EeDb&Yhn1Po#?fV6T_4th7f@|gs)(rm=@|7MS0;o2c=pf69 zKEXpu0Ggi?ir%4ELZtQpE^ll{)K-H^ZFW8s3O7e%u}dtBITE=L6cEUP7dvbRBvAiu?>&MW%lBY~a5K3O@VjI2 z_$127#IcyoO?qp|F)!?JfA}PvN1sBvgfKr(lPmJT#XQN8p-@ZJ^!E!u zIu^o;j{T_q#~Zk*U#@pJ?A?+inH5DT2t|ef8^{S|`l~^+3pFFp!gTBfC~iuWbsU7P z)AP(xNQ@*Vem8J(T9$}z3y>mjmHqbXaDDO)7A#dON}aY2R#D8@f9V5>M1ovzZ%-Ci z)!9D&8yv^mk-nRBuI5T54#w76NOQv>0+KUeneien2CkLX$mHcDk*hfIeMsRcDCV+9 zDX|}9Bnk*H*OPm6I-}*=5-BV>^=m3YvVsUeBQ37e zlLxiSS7GmY38Kpki^=rew4xLeVD(P1ZxdZ*mC|q*8rMt~0Q*{9WDi539VBEk$ ze|~_#iXSe_ehc~Ca)$|WwA5>X zDG0txkgVL2D7We%vfTCX5?fgfu=XUmjp|cNEs|EaSl0qWPXq7$1`-Q}mvj?3QKzrX zRYJBEYg)M=8)P9A24WEiHqM-t*WNy|ym{$qDX#et;Gf^^RH)ZcMr zBQSk(Y2A@=it{B>5F{(TR8CxyBylg_)fO@Y5)o$0GKfY4(#hC-!EQ(d29sg`gj~I9 zlTvywydRxISs4!jg%-ys(GGS2%fEcbmN^N0@JP1gG^&QUmJMAjF9DM&q-c1~LlwEB zF=KHu8ksEcfY0X}Uzqofu(UAMZHIq`bVPY2?HdIgFcH5b*fYy}i8yyj2Neb~6-oZEbC* zr!HRj#8B;qb^9LN8YbNV9;8@aD}J3wO#dYdKKLD=>&IE(M84a(P$~Q7$Pt&Rf3<#( zAoaL5Io5sn@L_K*{22nY4`k%h#fc*UvZUgP=a8aOoE@P&3+0*)pUo6^J_fwo2Aq0f zv0t!x5iUG@UV@oDOSl{F!LkES!sGGc+_|&A6Zi%0DE7=EZKdtl{C;2GAGS0%H~3D! zf{&kg40hU(DmDN%6Sq#!-JLo8a8gQM2PF5aG{;93d zr2LufB@}vIcl6J&tl5GO`}?o#+O_MObRbD`AF+Tb5@#V%SNlo_*$-N5?NtsuUJYjV@?cp8u-$elxW9)yLQ6!vq}9VYuDyPba{>V%Yhxp`n3!#B}7X1j9l9)lewd@A1t3@z9||*J+Da^8r7V g!2kW%@jnF^01P!{BekV+RJBrq+R%hZ2_kV(m!!4Y z&;T}$t$4x4U5Ugd&cA0=e?f$-W~f*Ad&hjKl-FIciz3{p7Wjc-Y2N4ijVUV z@i9L#`xzM-xnn_56pfgN(&;oT77JW1*A7)xnq!Id14)?HrXe{5K#-6Mnvl9-v&iSt zigGd-3|&a2QraH2Ul0U{Vz#ZDHf>r3aJPqTN+y$#Wf^Po^S%~Mq@JBkdx`{y2eJ@= z7`g>Za+w%`l*OALb(d5v$m6{;&%gqg?}+QCX?x-J#aVW(P$Jdr{i9S z-S)R>$$@jIIY)^k^*9sIK^4A5ZQ>*LsChztNNGuQ+prrd6`)>~Y;$L9n$YWsf(-?4*8<&eHdiMhz2oLOzB316k= z6>ZK;1HB55QC>vDC^_;4RK5QyrY*&0kIUUDNs@ylv@sN7#_~+2dOhAhEIRU0IoJ;S z@!ul-DN2-TL(t6JYBoM{5@;L;^2>oJy_;6ogh;z<|K18_@#0~Ct!bm4fc@C!Ukt_gI8a0C1 zx><~=kR}Hq=kPeDxN?`BV&4DJ%2y=P=AC0e`8GWqDcyrC@5G7sG?|x( zZvlQHhF@|RP84FY6wDo;dr@Eoa`CR@#0?!}tcr{VX{p|`j9Wr05#04gP+!f4;VeXm^V z>mISJsY3ZrUc|z6N__IfA_-L`ZhZzs+HjjwNmfMA=gE47mS!l={oVR>)h|1=rP0B@ zR}UOGFho_TWJ*!`z!hE2$?**rmy~_EqJEbk6kFkc?G$2UamuAPIJ%>1HI4ak2-nY$ z)DuuIyavo(q$`?&Fy+nkZK5v1Lwp;L{R7T*Tk&2`&v;{F<2T6A1Xi;}H{<;I^QpSJ zI%c2L-u~R>($dne%d+X{`aNy17O%tQ?|%uQKaoJ{#kLca(^xG$3{rV{{-cw*3X6Q#d8eE5lx ziS!Yw|9PlGpN0DFMyT(sgWA&|sW(sjjBQgB zMBP0-6OXsF)RRm)P_!0i;=1%6mH}XV$Q$f5ceb{+Ry_ISH-BGS|6rZZW@~07*qoM6N<$f*hU_wEzGB literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/accept.png b/spec/test_app/public/images/admin/icons/accept.png new file mode 100755 index 0000000000000000000000000000000000000000..89c8129a490b329f3165f32fa0781701aab417ea GIT binary patch literal 781 zcmV+o1M>WdP)4-QibtN)VXQDpczE`xXAkUjh%RI>;okxb7K@0kpyQ1k_Y(|Oe7$m(^ zNYX>mI||sUbmn+c3<&FnE=4u#()KBS^SH8e)Qs5i!#lY=$-1gbH6VluzU=m=EP78&5vQ z-?+fFP-G2l&l_QzYealK$;1Rl?FkzXR&Jv@fBPNjCr#AYRyJ7UJQ0v#?)7Ott=>3`#-pV!7>9}>Q1jL)H6h&gkP@3nI=+F3nA~M>u#(n* z8T!#8oEw&-mED4!h4s!N@Jo3S7N&Q6%6l3}nlcd~X@>;uelvPsSkXIgg~e+^T1zSf z3SNj(5%jK~i8@b;C(s)E@aY^3 F)&O8RB1ZrK literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/add.png b/spec/test_app/public/images/admin/icons/add.png new file mode 100755 index 0000000000000000000000000000000000000000..6332fefea4be19eeadf211b0b202b272e8564898 GIT binary patch literal 733 zcmV<30wVp1P)9VHk(~TedF+gQSL8D5xnVSSWAVY>J9b+m>@{iq7_KE}go~11+5s4;8hc+i0Xa zI1j@EX5!S+Me6HNqKzU5YQwL;-W5$p%ZMKMeR<%zp69-~?<4?8|C8S?bklXr4v&Ov zb&06v2|-x?qB`90yn>Qi%Sh2^G4n)$ZdyvTPf9}1)_buUT7>`e2G&2VU@~Bb(o+Mz zi4)>IxlSY${Dj4k={-9RzU^W5g9|2V5RZ2ZulL9s2xQbZ@r6eP9Ra5u(s|C0Nj#&4>wTSkb?%#=9?@ z^oxDy-O@tyN{L@by(WWvQ3%CyEu8x{+#Jb4-h&K9Owi)2pgg+heWDyked|3R$$kL@A z#sp1v-r+=G4B8D6DqsDH0@7OztA7aT9qc1Py{()w`m``?Y0&gi2=ROcc-9+nU^I6< zT=e_Y=vSnG@?3Ue{BW5ONFttcE!R-R_W4O01|0-|K-YNXLo2`4Qv z`r1LxR6#yf3FB%T95gJnaKKivA~Z}S9A(ZxEDK}O3T04USJ P00000NkvXXu0mjf^IS-S literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/arrow-down.gif b/spec/test_app/public/images/admin/icons/arrow-down.gif new file mode 100644 index 0000000000000000000000000000000000000000..a967b9fd5563a0fc2f5fde8ec0f7de3fc8fbc5a9 GIT binary patch literal 80 zcmZ?wbhEHb3wfn>L+1d2-{%jW1rjm^pLi|Ns9P7#I|PvM@3LmFNK3 i3?Q`(%%TyyyiA!oB04G)Te5yh$2@OMO7G-kum%ACMICAY literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/cross.png b/spec/test_app/public/images/admin/icons/cross.png new file mode 100755 index 0000000000000000000000000000000000000000..1514d51a3cf1b67e1c5b9ada36f1fd474e2d214a GIT binary patch literal 655 zcmV;A0&x9_P)uEoyT++I zn$b9r%cFfhHe2K68PkBu*@^<$y+7xQ$wJ~;c5aBx$R=xq*41Wo zhwQus_VOgm0hughj}MhOvs#{>Vg09Y8WxjWUJY5YW zJ?&8eG!59Cz=|E%Ns@013KLWOLV)CObIIj_5{>{#k%TEAMs_GbdDV`x-iYsGH z#=Z{USAQA>NY(}X7=3{K8#c&kkH2hg{xUB9fxq8%JG(R5 zT3?Eao`!{eDJnj1U~tLY{9|s;X>G0VWo1vp!yowhEs~V{|NlP&4xspxg^__loIwX9 z53-Yi)#yQKuEoyT++I zn$b9r%cFfhHe2K68PkBu*@^<$y+7xQ$wJ~;c5aBx$R=xq*41Wo zhwQus_VOgm0hughj}MhOvs#{>Vg09Y8WxjWUJY5YW zJ?&8eG!59Cz=|E%Ns@013KLWOLV)CObIIj_5{>{#k%TEAMs_GbdDV`x-iYsGH z#=Z{USAQA>NY(}X7=3{K8#04QSjDK;;f_YpM l_F6xkQ2UV8Nohx7^74tvk@L9Rj+t6N-Sy;6cK`!}H2{>{9sK|R literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/edit.gif b/spec/test_app/public/images/admin/icons/edit.gif new file mode 100644 index 0000000000000000000000000000000000000000..e1b9afde65cc924df232aad7c1bdd753dd8e971b GIT binary patch literal 119 zcmZ?wbhEHb=I*&Aa=g_Vl48 zmH)wj0Spv>vM@3*@G|Itcpx(vSX4HgyeYC&>*nrB_bxSQsBGn6*)YRRaLr}Q6>6LJ P$Rx*~-FRR+2ZJ>L#Kbnb literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/edit.png b/spec/test_app/public/images/admin/icons/edit.png new file mode 100755 index 0000000000000000000000000000000000000000..0bfecd50ee9f5bc5828f0c0745aa3e0effcbe250 GIT binary patch literal 450 zcmV;z0X_bSP)Rq1}l<=psl5*5Xz9i;M}s*NP=ugs7Q#8Z;Dyx|}!`#}xw_C3!B-yaPC&0j)XcpuX@rNfq|q}N(wJOjA& z>u+z?dfJEuLePrqzy!)73pvLjxk4d6XNZt?hm_iYES{i}J5y3l?}PPNYDBR7oPc~6 zL^d)Bi4Q2L3pnp!nFxN9c2E+=@XAl&+;2m6a~kZj1r3Mz3C=hmUG<{+vWR@t4q?fJ zhFc(ozZD#Mx`^Q~g1v=K6!QnfuqyD4>U4EjF0eamL}Jx| z%&`kR-H+3GBYr*Qx}frLU4`%n9(`uSomzw)t%%NagXkA*R5Mbv9VLDp1wMo$cOMa~ s3Wm%r7^bwK$2$}-<~D8p`#1iScU4^XCLAA~0ssI207*qoM6N<$g3sK(Qvd(} literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/email.png b/spec/test_app/public/images/admin/icons/email.png new file mode 100755 index 0000000000000000000000000000000000000000..7348aed77fe6a64c2210a202f12c6eccae7fcf24 GIT binary patch literal 641 zcmV-{0)G98P)Az`{eoOom?Tf*9)f$7n8&|1&5M4#i^32;+&E? zC3Q;bRFQN#y*%%=_V)Mfa<$xe^kB0TO;vJPkN*k(2v-CI7)OaWj?&eKPos(H4wGh_ zIC;6#q1B5SMap5{(Hc0~XO7OfqZ=x{kupu8-H&9azl`L1pTuu^Znm3EA)kCoG=JuwsyNLEtY83i->Z~j3y~F)`RA1k>zTES07po!kBVS2y#L{jCt|CMY&v{ zxmqM|`OA#P2{R&)OcQd}v0kt6_Dh#`Z$i5_;q|93je3Q^PcfR{TmBHRmr;rWahz~G z2x-&;d_O~HkmKXt5Cd#Bs?-+qj3zOiUdU24KowBIUPg(gPNmxqX)Fiia~V*$y;5L( zrGNmU;81MA$F2k%oeUXQ@}N%bXz=qOij$4IYk4W=jfhDxfCz{PGXe-#ge#VfYTyoj zh4JvDePrW{lf(Oux2xG;VZmlSvDU+Qf@i=O!B`MLglhttCUHDIKkc7eOSYYtbpBV}~vsBnU!_?2tr-P=|^T zED%wc9ezHgW@NMb!^uT_|SvCpFLJylbx zY%bpaTGI8IYXMN$9w<3j9VkA~NYOKEQXsj?6a9_hcwfU$acAhJhB)zb_w@MVUEy@S zX&I>K-R!bhu3?(6bHWIg$HEl7{9g>>&l_qdd+UYb(1~BCo9LptNq&8>!yoJ3Ui(i5 zRJ|XnYBklL!{@$-7=3mJ>P@1c=7Oc79e-V7yf+%lD2!I;Y&nXBZ>=B!5?CB>LvEx6 znI%n)qqi$#X#wKB(U7XP2P=+4{b@j#r%9-K(8UqtSDk>0UKzf*HM9yqMZ1D!$2MdZ zR=`U>0zhOH1XqN?nY@AQqB7)Fp4{v&dKXvb43hZKvnN8;Po;+jY*}~*Z|W9Q0W%{D z^T}Cc<|r(Su=1K=P5>Z4 zg`et&Va}tdzBS-G-ZcO)zCWpJvGQwrHZ`@wpM420ac@bI5~KkTFfGEM3sPWO8co4^fI6lPnA)Y{ef%@{+SnoUk0+dW+*{8WvF8}}l07*qoM6N<$g7cXs A&j0`b literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/exclamation.png b/spec/test_app/public/images/admin/icons/exclamation.png new file mode 100755 index 0000000000000000000000000000000000000000..c37bd062e60c3b38fc82e4d1f236a8ac2fae9d8c GIT binary patch literal 701 zcmV;u0z&N#0$9Ug7g~-`rQ^qx~m@y2OU8A z#zh~=7n#Z$Z*fx-GOtDf07cgx0suCz_W(2~Y(0tf@FX@P6EPuM_dgn$vj9LucO)%W zw%HgMW>=#oL>nZ>M&NEf08>)#)k<{$fCT_r>rPi=BV=hFh6WS^qqze>C6Ek}o{M5% za|@JGowu0t{&hgNzySHZxy@LTNh);YzZ2zSp_ zl$^T&Dnc|NLb&RD_!4>pt@VHdP)ZGER%5ZmWEe$lryR&y;2u^3cOkO4#6c%-(EY6a{600000NkvXXu0mjfxS2AI literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/feed.png b/spec/test_app/public/images/admin/icons/feed.png new file mode 100755 index 0000000000000000000000000000000000000000..315c4f4fa62cb720326ba3f54259666ba3999e42 GIT binary patch literal 691 zcmV;k0!;mhP)bpQb1=l6TxbDZwj&S={?7%qx-u`rsG(Zp`-rh=e^=%((1yvsuf5d=&62Zj)Y zH&JviNS_F4_Hj|T(1j4$p-!}kixP9&dB4uv^MveG?dGf%sUCoc2!IFxD6wHRA2^dX zXRVk!-qSfk(jcaUKn#RP48(whfPlJUpApdrA!TQi_4D+fVoM;3I0gZ8{=Xv~Po;geVA+Em9@0Wq2 zr>OTZEGR05L=gf1T;ucCxq6Q6EgJiH@@-lVaAlQyw`jIF^c=&IVnj|95hHbE_cnt| zTzZQ?F4Ne@(bH(~&3nM%m)I@ID{@jJ2qZPjr)jhpe9hViOwH5k&|T#EmmL3(vHeUQ zq^!t^Al6JD;=mHq^Bg?J-8-zG2Od7gZbknG;K9czYjPqG*xjPo0k(c4%lPXTpw(qq z@aGMnxtFS(np+2kC} z7P02O874ZkJH$v#nCUVx$({yDN`IX@o2wyvTD#e`qN`_w5<}$3F+_~O9lw>B8WRlD)Gm}Jrz31u-X&&gn2lvjs=i{7nIaL6v2==uw+8Lcs(8j27 z;|c`rmSv@Lx!heopGP^^Ieb3f=R!%Lpp$}iMS-&P3EJ)s48wrJ_Ni0~k|c47D2nj= z{jS6bt|kFpFf|p5cM`_&0Zh|`rfEp0(}=}lT#(6RpzAsUfxv^LSYX>WlAaN$>)*J5 z0#sE+JRUD8iT9*fz{)_^7@6P&!sEjTcD+I9Z4YjT1`wH@fV{cEvneYGFU%maIEU2s55&K(LixD|{p-uiS@?KNj zk-Go8G$hH6g002ovPDHLkV1hVj1#|!a literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/reorder.gif b/spec/test_app/public/images/admin/icons/reorder.gif new file mode 100644 index 0000000000000000000000000000000000000000..1cbd3061a6733085749b74abd6ebe20a60780dac GIT binary patch literal 84 zcmZ?wbhEHb8@9veO&B literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/search.gif b/spec/test_app/public/images/admin/icons/search.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d5f4c74923af2daba13baa484364380fb1614b9 GIT binary patch literal 552 zcmZ?wbhEHb6krfwc*ekR;r}fg8=Jp>|9X0Qe){yu!NI}X+uO&-$I8koH8s`3!otqZ z?(W^YSy@?TW@e{PpT2zg^6J&ABO)T)-Q5!s60Tjl=Ire3>gqaW%9PsL+PQP*Ha9mX zCnrZoN9W|^#K*^f{rYv@ym@clym|8E$=&V_@LPJBVtE(?uxDXW;RaaLxbLLEYd;7Mww%N01*VNRUKY#wgg9n+J znUg0^j*E-y=;*j{51X2rQc_ZG-@bkS{(VPBM~0yT6o0ZXf?TTuB0zD%z~0)x z(A3=0+M*~cF2*k1)@;Hotjo#FYS$;lCc@9cB5K1e*(T4%&$OJ0N1L&YotI^~f{vr% zn$~qnssdI5qW0Tb4Ak_r)E!)0jSnm~~hECZvY5o%BVqvfb0K*)eZU6uP literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/send-email.png b/spec/test_app/public/images/admin/icons/send-email.png new file mode 100755 index 0000000000000000000000000000000000000000..4a6c5d396ad024567a769d1f2285c525bef8c88b GIT binary patch literal 754 zcmV~0d>kmp9&fG9>#5EaEn(MD9Xvl47<{Rb2T3D!0$wpy4@P!Tnn zB0fxQ2!aPL_fZ@!=Wv9zmj8jnf5JO`<=MmZs@#@p z5O*{}9L5B6J+L7ORza<+9h)-B~<&cwIhUkd?cp4is-ziNrfY^u-7xdbFt=#%1534Oi8ajBBo}VZvCxd1 zTu*VtX+~P45)Om?dG5aS`PPW(%?lDPBwaz$6C^$8$_Q#plJTjpbgj;_rYi*?oK~m+ zDD`C->dkZKh0j6|Q^-0bJxIFHnHJOo$@r8{VNIUWU>31rp3@BVvYIZG2D0>Yuj2Y- zg?b?AObc>pK`oG+zkPsr3x_BTWXX8H*w}0@e;@>?SdsP&!-HMidhRn*4VkHi+<58} zTg6ae0~aSoNqRq(^;(g}0#Yiz)&q*YIg-f)mmeJA&3%nD3aJ$X-6L%1+fEQRIeTL* zS5K6|3cOaNtTtBowSZzzj!ZfM7L<|f+jtyp4ccf7mf6J$n}&ALkZlfLEYRoNvtG0Q zzJh|U~_Rdjkv}0kGt_?V}5$?sXN`N zTt|nOa)sx)IIf_-7XW**;!X9`USPjuUUsJrREk)6q*M9ZHEb zl2A!T3LBjrrTx74{FsUNcVA1zw%IWoiGNMw=s9P8>+qh!B*saR2}S literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/stop.png b/spec/test_app/public/images/admin/icons/stop.png new file mode 100755 index 0000000000000000000000000000000000000000..08f249365afd29594b51210c6e21ba253897505d GIT binary patch literal 715 zcmV;+0yO=JP)C4}Mrzlg<+1Y8PEBfUp0jJpx4B>@E+cy3`^(Gw`Mf+2&yxZm<$to~Vpgvg&QKNR z_f#1(r6svZt%iF?s+n<8X?B&!h3g9Dbb8_=MX}!;HiQSAh`bp^WMl~Z-44teO7W_Y zV4thSL{h;rJY7!l3%5J4H1!tIzB`Dv+YxO(haWeausGZYkI8^hWj6mzo=L0{%;yxzh{5!Htr?51 zvG|W62MzC8BZ76hRpCyO2zOn<%e)K>NHge!-~)Ap33OdWw6hsLYbCxGNt0%wk_2z7 zfyYvXheSG)5HRK1VB~%mq7Dmurw#bi@hEcOr3&G1ZiF*$M=&9nB#VNf&Q^r$4G5kp zTURh&s)E0%5&hyVD}sp<72~zmAY`Y(9aqO6CXF%=zFHGzO-A&I(pE}v70YQxCPJ{Y z4L+?5-crdLn3ZRPEs!A4ehEY3ZRpL~w9>@aMN+{F4dI@v&>(QDHQum!mG~E^$OS8l z!7?%Uwib*ROP67Hw`ika)gX-(8Ia`-u_IEhxG7U<13kSsMW+$lbb2dUMm5p6pa}cjgA+U$^mJ^AjD?&bdi)8~y+Q002ovPDHLkV1g8IMc@Dc literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/tick.png b/spec/test_app/public/images/admin/icons/tick.png new file mode 100755 index 0000000000000000000000000000000000000000..a9925a06ab02db30c1e7ead9c701c15bc63145cb GIT binary patch literal 537 zcmV+!0_OdRP)Hs{AQG2a)rMyf zFQK~pm1x3+7!nu%-M`k}``c>^00{o_1pjWJUTfl8mg=3qGEl8H@}^@w`VUx0_$uy4 z2FhRqKX}xI*?Tv1DJd8z#F#0c%*~rM30HE1@2o5m~}ZyoWhqv>ql{V z1ZGE0lgcoK^lx+eqc*rAX1Ky;Xx3U%u#zG!m-;eD1Qsn@kf3|F9qz~|95=&g3(7!X zB}JAT>RU;a%vaNOGnJ%e1=K6eAh43c(QN8RQ6~GP%O}Jju$~Ld*%`mO1p3wfn>L+1d2-{%jW1rjm^pJM!zdUHfe{k|ia%Kx8GuSOX;Q=NFCLWFl0*@NH#f6pb?3n1_z+epkX4f1j literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/icons/xls.png b/spec/test_app/public/images/admin/icons/xls.png new file mode 100755 index 0000000000000000000000000000000000000000..b977d7e52e2446ea01201c5c7209ac3a05f12c9f GIT binary patch literal 663 zcmV;I0%-k-P)^@R5;6x zlTS!gQ5431_q{u#M2 zg&W%y6a}>qj1Z|7Vu&-DW6d~k-n;jnHsjb-q#u0C^W!_5^C=MlKq<8oNCQ6qS00!X z5eI;XP=g!^f}j{hku}E1zZ?XCjE;`p19k(Rh%^AQQ54xysU+ocx$c#f61Z4HnT#3u~FR(3>BnZniMIF4DouI8Hi4u>cAK%EN)5PO(ip3(% zIgBx+QYirR){Z8QwV$9Z(Mpt=L-Or3#bf-G@66}txq0yc*T(zNTBDT0T8rO^JeNbSI-Tzf5!pBioy4NwAN^?iN#{;fH1Jke4Xa`^fR8m z%h6dq%xX)S?7`zae))(Xst^Scp6B8FejQW?RLTM8@0=vnnntuRGBM2dpo>gbCnTD= z^<;=JuqdSf@O>Z8^XdR?s+KEfhDdB_#ahFj^giCtzT(s8kA$AViyTqaAR;KGaLzUU z<=GqA4bRwpX|IG~*x>pZ!@zLr`XQ`od>m(`;jz|M_*1GDO#$7;n74ppb8=eiqh760 x0yt}J1#p`gw$`o!R{d7zU9~!Un@nJV{4bstt4Au+Up@c;002ovPDHLkV1kWhGjjj{ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/tabs/off-left.png b/spec/test_app/public/images/admin/tabs/off-left.png new file mode 100644 index 0000000000000000000000000000000000000000..201e23c9fce8a49357672db5c873f4ce1e4e25f7 GIT binary patch literal 357 zcmeAS@N?(olHy`uVBq!ia0vp^CxBR)g9%8+?Yz_hq?n7HJVQ7*IBq}me*oli7I;J! zGca%qfiUBxyLEqnf-)tp5hcO-X(i=}MX3yqDfvmM3T~N2spa`a*~JRZ!6s~*E-wJ8 zd*JEf7*a9k?R7)0Lk=RY7k}D2Z{SqYj9r*r9PPw4QKHi`z$fPl?~LOI3j9rE!4uwNrvzv-W%IATUxVbBm@1*;OXk;vd$@?2>{*; Bf{p+H literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/tabs/off-right.png b/spec/test_app/public/images/admin/tabs/off-right.png new file mode 100644 index 0000000000000000000000000000000000000000..d41182da205478b28c53cae9a8754e2c31765279 GIT binary patch literal 296 zcmeAS@N?(olHy`uVBq!ia0vp^96+qh!2~4L*zRZoDdu7)&kzm{j@u9Y9{{nE{-7@6W^Y3ACV z*R5+}cl%vGY8CMN0Eg53Dft2E%UT!CkX_LF|68*>|MKG816hu1OkWglu;-e7@7CF( zryYyx8W%;uEmy?tx+*r!-Bq|~{TtTaB+pdm=r2L7hFPvh!r8fxq zh)(2|`sBQ5veGNIIfoy7unRr4zQWR3=(#)px8w`Ccjtt;|E_NT+s9ZhP-lNP{#y9) zP~-UXVY8RNbU!vbpyB-nx%~5Od%u0Y{YTr)`185cyhRsaK) N!PC{xWt~$(695dZs4@Tm literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/admin/tabs/on-right.png b/spec/test_app/public/images/admin/tabs/on-right.png new file mode 100644 index 0000000000000000000000000000000000000000..e178f277a9a32ceab8b0592d87b148d36347440b GIT binary patch literal 352 zcmeAS@N?(olHy`uVBq!ia0vp^96+qh!2~4L*zRZoDdu7)&kzm{j@u9Y9{{i_*SpCFi!c<9QZ10ZmyVzh}(J-pypHDSV< m=8r&EMySr%uv(r`h(Y72(VGyx3HyM)VDNPHb6Mw<&;$Uu2ZNUY literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/ajax_loader.gif b/spec/test_app/public/images/ajax_loader.gif new file mode 100644 index 0000000000000000000000000000000000000000..d42f72c723644bbf8cf8d6e1b7ff0bea7ddd305a GIT binary patch literal 1849 zcma*odr%wI9tZGc_iT2vk7P+x3@LU(2yGIQCcHvgYTblq0THkTesI znR7n#{hi;OjP2?A&1ME-pkE;9;lqaz1T8KudOV)_`T6wp^p=(uf2Fv%SSFK=kB@u3 zUZGGpJUk2l(CKv5)z$vpzrP~?FHUK&nD<(COPZ{Et0m?db93z;^X^U7=d1QWkq-bw z_z#PGNam*Pcq+w^mln54i-h<~s=yrqB!o6eBrwd4{B{&hHR9I{{bQLC?)mG!al!d3 z<_YADRELlGj+H!fNocrRe7`?$gk5?^y3^@6pC85jwesu>G6*{Wrto)mL5D?z)j-L++&!SNH!MDuhyZ1*)jGIdEgHH>qdP6}DTp>kJ!bZd!oke!Q0J5vRHHSl&=?=ft+HzcfBB?ZKg#rgtngf(C zDL)0I;%QR6Z_49x&crpS#vVCUpEoP)gxevZsOEytw5Vq|*bf39%i#K5VVMGzL^=13 zR-}G|UaU(m68*HWc{(R=BrQG$CK$N`HcDv@S=IAWm(o~Np>ZF8X|_V%3_!1*u`vm}?t+-#K2Qs= zlXouK&f(YJG|lD7kLqye?NcYji#s*HOSm|xQ~{R)Ao3VZxwQ7l4$VQO;kkhWM?7Tq zV7I5-(5BO!(yinIf+@AjEfNKCk>b~u*83@)>qu(a3nA*y_1a7za7?y8mYaN9Z=br4iilUPLeBE8>z7SjUY!R@qdmA$~nkLiZ z9qy{OsKf4~y1^q+D*!YY&=vr^tMUUJQrx*Do>dYDlPO!l`DoZR5vApf95=i4Lz;yXc(}m~6Zh#oS@fHF;-MHT+t;8_YoNLuk zSUE;16g_GThjJ{n2e=qnXWb70jIOhk#;lMy!K4=hr0tBKfB(rz4e z+1U)aJZHl#TYU{%(($JI!F!<+%Jp+Jdk!#Y(|CzO!nka;h@9x_wBI_{i{tgbHY(SI zVOYV2N)E%tOc-CGkW(0fy>Or+s~>c2t0?1P8+jRZNqDzxRf7dRy(%%W_#a<6{e3caEW8DdD|KsdZBw z(K6nRmw&K{D1uvtp&1a;%;nPiAvOlI0*Zq9*kdsS7JEd^O*1FLwTe{>9&A}oMlrlF z`pQPbaQ2zQZ_j_#qk8qy|9IetJFQG!>l{9_AvsafGtVRnQr)xR?bImN4qo-#?gP`}S)0UYaWY9t`6HQwY4B_($TWNu`l?!*nIBy_|7=pQc9cnFU zs%%oO^oje|8ddh7^1-E9_|T~KBxydL{KcW06CqFQ?Ym3~cb^|wPx?lUyCBD|_nRZU zsA}@ctKd0_^(q#G?{G;+$w=8-md|N>W6e5@3AT19SLRCCSyG z=oV%uMus5!Ry9PhrZMnpmb0lXJuACSOl2|krLXzwsrVsNe(8N);u`z?E#W-RKNi9E z;z;dGgCSKfqEhya^?xWt|DBmvWexQ%SfTtu(C0Mdv9@(g3WttPh3GsE1Niv~Ituk; zXltbvX7Jn^Z4>QMtd0~JELrW+CaT^$N~khm@~tceYLLGjk=3uK@XnOQ1!btG^Pus9 zYDnDM@%;wTR-(h+ec@l>g6c`Cs7=j$FkqTfajDLuzmAAh_qHK0!$~G+eL?P46^V2( gTVr?dnQ{(H{Ie1a9NS3OKPMyDfF?Qc5iPGj047fkWdHyG literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/amex_cid.gif b/spec/test_app/public/images/amex_cid.gif new file mode 100644 index 0000000000000000000000000000000000000000..13d91deeca03d7a1f968e7287f0c86f82171e053 GIT binary patch literal 41739 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≶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
GZMCc^1x<=b(c?@U`0xvye<-toU=0>>j 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

O7pB#TYE%A`5TNO=p9 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/bg-button-hover.png b/spec/test_app/public/images/bg-button-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..82457c0ba8ecac5420c16165657b040265fd1c06 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI}!3HGf{@&OHq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c75RF)IEGZ*O8WQzf4z|~GxK5jm?QBzIxOGy#opP6=sEEy z9jy5KtJE_sIXPJ_t*)+4?^*u+eT9riC0!gg^(Zuno^w)`DDa%HZU&>m0fwck6!^Dl SDDwdgX7F_Nb6Mw<&;$S@mpCT? literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/bg-button-pressed.png b/spec/test_app/public/images/bg-button-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c7e8fa98bf892e7ba04168ec8bf34c834dfff3 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI}!3HGf{@&OHq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c71?^aIEGZ*N=isbc#y~>#Ixc^{j5&M$W^OW@%T)eHjT%J zkB_g1=lc5i^zwc-5TY|NsB@?%jL$?%ktDkG_BZ{^!r1=g*%%efsq4*RP*Gef;_J z=fA)I9zTA3_wL=7uU@`+^XB#IH~;?q`|#nz@87>)zj^)e;iLNx9^Aiw|I_EsKzB`;KfikU^6AqjfByXa^y$;9S1%vjfAII;zgI6`{rvUw z!^aOVU%q_t{Q0AY5AWXx%G`hT>J`wuU%!97dHv?+&tD%teEjqG4+CzX_>+Z^fx(J8N2U` zd8-L?-+2FHcHQ~+zyCKhHZ`}jwzYS3c6Imk_VrJgIBD{fsne#maka3YW146>(+1BxM}m2t&O}pc2qEm>+7kB>q<+Dit-#k&aRZrrjwznZJ?-; xXq*rmBV;Nhq$MjMp`gMc9}*bArO9O?V|6H_V+Po~-c75R9&IEGZ*O8WQzf4#aeGxK46fsfKtU0FV|Pi>w2qgz2@ zef<7)XG;G3_*j4DkHdjKZ*QC1EwE_j@t7v)vf*%~Pl1@!L6;>Gd7KRl%nXu-O0U1R SeDwyJ%i!ti=d#Wzp$P!_%RJ!# literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/blue/left_01.png b/spec/test_app/public/images/blue/left_01.png new file mode 100755 index 0000000000000000000000000000000000000000..07d494e85388a0f3cad55271a582b9adfbe06f61 GIT binary patch literal 767 zcmVL6*jXrONRecB<~V0|1Nk#VjV6119+>P8 z*<|-LFYnAZJ29mc0H9>?{*#sMk1sUaa`KC;OX0Eolf`l zmFri-%a@ggs40Fs5fU=ui6LzLC0Vq4{>J&B{vjd>yu&bM}8=1xg zp!l$JsUHAJ54+(|*a1*-*flvfs)Zc@1&3XG>cJFFW9BK+x=L*`twL;X)1;~96XomX zBc&MH-%0to_OrI1xV=r2%k`zO^SXU8qsdmEcz1K_xtT^b)N`}J^}ytW=sH|_{GjSYa47IxJkr!nhxZ|ClCi%J^+ zCp_#XgCak(_nb802Ef!cyKwNBzhDDkip^L80RD%t`yAuQN&rxF*nQ}1d=Ie}cmR~# z?CR0WxwTJL1At<~E_=~k|GF~2`ccCJpg7%a_aArHzpV8(zdf(Ir$W`~h18j~LI4yM xc5TCJn%%4J=IWpuR&O+qFIpl1rri$#1^|B?K8&Vb_%Hwf002ovPDHLkV1n=2YD)kB literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/blue/right_01.png b/spec/test_app/public/images/blue/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..f49cd294aa73efd1997ea6258a889070199a02fb GIT binary patch literal 416 zcmV;R0bl-!P)C5`W49re*5v8;q{wO4A-vSWO()b`E;OACD7oHAUT#lfB%u}JT_Kl z25Ct_AhuvQcj->%^^2GP0)=xya!kL0OiHk}rZR(&n0QV^&Wv!dfj|HJW1s~8{`a3j zQ%4hIRwl&DzyDDjv)tTVAj$x2AQj95`jZ(%@`DZh_2(Z|(;>_6zyGOhASkM+Y9Mue zOr2OpG4Lm~!|)HaWBJd2s>d?5z5I{L2Ht!5ohkI)5cP;^2C{sA1EN+^#X#mi-x=6{yZ|w$gAJ$1Wk23CaD06T3d3Sx>kI5<7S?Ys zNq5!nuRxc51BTtV9nd!7Cb%UWUmngP!*LgY_&Cs@3+NI60R{jNM96)h3W$FI0000< KMNUMnLSTYx9JZPO literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/body-back.png b/spec/test_app/public/images/body-back.png new file mode 100644 index 0000000000000000000000000000000000000000..f1bf7773c9e901ee5dd95add6bc154c288b7a9d5 GIT binary patch literal 254 zcmeAS@N?(olHy`uVBq!ia0vp^j6gJvg9*qoORk#;q$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c6)o^|aSW-r_2!~CU$X*3OX4NxFH(Db*00yF3k*ECeSw+j zS(TRBaGiZe=by z8%tvoZ=0Ro_kO|FZ4${k#|tgaeJ-il|K}%%0mETIn>F*<-aH4omBG{1&t;ucLK6Vo CjAcgv literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/bottom_shine.png b/spec/test_app/public/images/bottom_shine.png new file mode 100755 index 0000000000000000000000000000000000000000..160a8cb2edb50043a8c4a0ce64bc58205a440de2 GIT binary patch literal 828 zcmV-C1H=4@P)u+7GBjJ3XosZAY^$_h@ znEREc(c|mczaEav(<2W03%=C|J2YNQx#X3D?a7TA3TVb!Mj{N65j3LOQ-++ET<{cx z2xIY}9280LnWs+)+M@Zx~p0 zewU{L0zxVgeL@6*M;fj-vgxsu=asbRj(MlYaKaC8k|S}eS&3N+VTHRGO-mY905UA@ z;arMR35CRz;WBCYx2A3cHv~JF7Oo4-qykDsg?bW8e8o+HMZ$)9L{PDuAl?XGxUiX& z*Y+Ro3DsvKVUXPxO8HVlc+oLRoag{An)J2C?+}bOA52S{(nD{~n^ZzzQ5}^j0YDpO zW~5mRT$vY{7oJ41pMj^)HN{jp1@zHq)-6n&%_*FCq{wly=G5#WWL+Ey%!}PZFQ$O* zg&i~lruA~M9UYF+xpD7(XC3Te>@<}dQKB;?Xo34if!VGl(%9oLk321h z3Ywlmm>l?o#v$lf9$i7)<`omwH7$cxB8QQ9ka?%ll} zfUa;?V?s;1BX`U8#4XT=MyY{_JL|x0qHNzYYQq?<86zE3J9=}*}{T&fIBW5X%v{qoq5iry&_k*=-O<`_GKoQq~^>V&wS;T#4N}WxZP_z6dDh!*yoC- ztK4knX`og{*x_tYC}#odH5{c0K?=;q8K5UtiBoVl_EsGFH1z}V8&~80B@50lIE%1{ zLIP}}+nXB)Y1mof9fIXUa1Lz4Hh Lralf}V6X-N&K(fZ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/button-dark-hover.png b/spec/test_app/public/images/button-dark-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..5d3e6fbb1d245f2f4403758778bb329fe8cbdd44 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^j6m$o!2~4jwp3jKQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiu^rY978H@o$ z&t)0viYFbLb5VV1+b!)rmrJvvDzY~HUvyD&vbFJg+uv6g{yu*H-fig>dtcmBKfth5 WB-eXQXv8C+(F~rhelF{r5}E)`HADme literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/button-dark.png b/spec/test_app/public/images/button-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..92b60e87f93c99b2fafa88b859580b550313f508 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^j6m$o!2~4jwp3jKQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiab1B978H@ojG%m_kaSAbD;KZL#OnYZ+$RolAfyzLLyGOysNe!a%$^66a+%naNS3AX#xt=9w1 OWbkzLb6Mw<&;$U12Rax4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/bg-button-hover.png b/spec/test_app/public/images/buttons/bg-button-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..82457c0ba8ecac5420c16165657b040265fd1c06 GIT binary patch literal 171 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI}!3HGf{@&OHq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c75RF)IEGZ*O8WQzf4z|~GxK5jm?QBzIxOGy#opP6=sEEy z9jy5KtJE_sIXPJ_t*)+4?^*u+eT9riC0!gg^(Zuno^w)`DDa%HZU&>m0fwck6!^Dl SDDwdgX7F_Nb6Mw<&;$S@mpCT? literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/bg-button-pressed.png b/spec/test_app/public/images/buttons/bg-button-pressed.png new file mode 100644 index 0000000000000000000000000000000000000000..c6c7e8fa98bf892e7ba04168ec8bf34c834dfff3 GIT binary patch literal 155 zcmeAS@N?(olHy`uVBq!ia0vp^j6iI}!3HGf{@&OHq$EpRBT9nv(@M${i&7aJQ}UBi z6+Ckj(^G>|6H_V+Po~-c71?^aIEGZ*N=isbc#y~>#Ixc^{j5&M$W^OW@%T)eHjT%J zkB_g1=lc5i^zwc-5TY|NsB@?%jL$?%ktDkG_BZ{^!r1=g*%%efsq4*RP*Gef;_J z=fA)I9zTA3_wL=7uU@`+^XB#IH~;?q`|#nz@87>)zj^)e;iLNx9^Aiw|I_EsKzB`;KfikU^6AqjfByXa^y$;9S1%vjfAII;zgI6`{rvUw z!^aOVU%q_t{Q0AY5AWXx%G`hT>J`wuU%!97dHv?+&tD%teEjqG4+CzX_>+Z^fx(J8N2U` zd8-L?-+2FHcHQ~+zyCKhHZ`}jwzYS3c6Imk_VrJgIBD{fsne#maka3YW146>(+1BxM}m2t&O}pc2qEm>+7kB>q<+Dit-#k&aRZrrjwznZJ?-; xXq*rmBV;Nhq$MjMp`gMc9}*bArO9O?V|6H_V+Po~-c75R9&IEGZ*O8WQzf4#aeGxK46fsfKtU0FV|Pi>w2qgz2@ zef<7)XG;G3_*j4DkHdjKZ*QC1EwE_j@t7v)vf*%~Pl1@!L6;>Gd7KRl%nXu-O0U1R SeDwyJ%i!ti=d#Wzp$P!_%RJ!# literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/blue/left_01.png b/spec/test_app/public/images/buttons/blue/left_01.png new file mode 100755 index 0000000000000000000000000000000000000000..07d494e85388a0f3cad55271a582b9adfbe06f61 GIT binary patch literal 767 zcmVL6*jXrONRecB<~V0|1Nk#VjV6119+>P8 z*<|-LFYnAZJ29mc0H9>?{*#sMk1sUaa`KC;OX0Eolf`l zmFri-%a@ggs40Fs5fU=ui6LzLC0Vq4{>J&B{vjd>yu&bM}8=1xg zp!l$JsUHAJ54+(|*a1*-*flvfs)Zc@1&3XG>cJFFW9BK+x=L*`twL;X)1;~96XomX zBc&MH-%0to_OrI1xV=r2%k`zO^SXU8qsdmEcz1K_xtT^b)N`}J^}ytW=sH|_{GjSYa47IxJkr!nhxZ|ClCi%J^+ zCp_#XgCak(_nb802Ef!cyKwNBzhDDkip^L80RD%t`yAuQN&rxF*nQ}1d=Ie}cmR~# z?CR0WxwTJL1At<~E_=~k|GF~2`ccCJpg7%a_aArHzpV8(zdf(Ir$W`~h18j~LI4yM xc5TCJn%%4J=IWpuR&O+qFIpl1rri$#1^|B?K8&Vb_%Hwf002ovPDHLkV1n=2YD)kB literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/blue/right_01.png b/spec/test_app/public/images/buttons/blue/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..f49cd294aa73efd1997ea6258a889070199a02fb GIT binary patch literal 416 zcmV;R0bl-!P)C5`W49re*5v8;q{wO4A-vSWO()b`E;OACD7oHAUT#lfB%u}JT_Kl z25Ct_AhuvQcj->%^^2GP0)=xya!kL0OiHk}rZR(&n0QV^&Wv!dfj|HJW1s~8{`a3j zQ%4hIRwl&DzyDDjv)tTVAj$x2AQj95`jZ(%@`DZh_2(Z|(;>_6zyGOhASkM+Y9Mue zOr2OpG4Lm~!|)HaWBJd2s>d?5z5I{L2Ht!5ohkI)5cP;^2C{sA1EN+^#X#mi-x=6{yZ|w$gAJ$1Wk23CaD06T3d3Sx>kI5<7S?Ys zNq5!nuRxc51BTtV9nd!7Cb%UWUmngP!*LgY_&Cs@3+NI60R{jNM96)h3W$FI0000< KMNUMnLSTYx9JZPO literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/button-dark-hover.png b/spec/test_app/public/images/buttons/button-dark-hover.png new file mode 100644 index 0000000000000000000000000000000000000000..5d3e6fbb1d245f2f4403758778bb329fe8cbdd44 GIT binary patch literal 173 zcmeAS@N?(olHy`uVBq!ia0vp^j6m$o!2~4jwp3jKQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiu^rY978H@o$ z&t)0viYFbLb5VV1+b!)rmrJvvDzY~HUvyD&vbFJg+uv6g{yu*H-fig>dtcmBKfth5 WB-eXQXv8C+(F~rhelF{r5}E)`HADme literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/button-dark.png b/spec/test_app/public/images/buttons/button-dark.png new file mode 100644 index 0000000000000000000000000000000000000000..92b60e87f93c99b2fafa88b859580b550313f508 GIT binary patch literal 166 zcmeAS@N?(olHy`uVBq!ia0vp^j6m$o!2~4jwp3jKQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>Jiab1B978H@ojG%m_kaSAbD;KZL#OnYZ+$RolAfyzLLyGOysNe!a%$^66a+%naNS3AX#xt=9w1 OWbkzLb6Mw<&;$U12Rax4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/drag-handle-green.png b/spec/test_app/public/images/buttons/drag-handle-green.png new file mode 100755 index 0000000000000000000000000000000000000000..43f2d55a24f1d940299ca6b58fd64c8cfa362012 GIT binary patch literal 160 zcmeAS@N?(olHy`uVBq!ia0vp^GC<75!3HFkH`xgRDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MNXbBjv*DdlD6bOSeuZLkdeN?_Ju{j|CN(iPwik{@;EbR zA>RqUWB>pEH@+Zjz|=fNiMe5+^QP9tg%(on&DMO3Ogs$ctr|6F0v!5*rZITB`njxg HN@xNApLH~{ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/green/left_01.png b/spec/test_app/public/images/buttons/green/left_01.png new file mode 100755 index 0000000000000000000000000000000000000000..c23c7229830e9ddf49f1ce48d4696d158692b3fd GIT binary patch literal 717 zcmV;;0y6!HP)4j zXY=FSKa(n@6aY}N>d~9Wi`SRC~8OGu5WZfcdQ}+6d88=TiZG4YSjRs*s!}0RYa479RTHqT^Dps92>#}pyaS?+cs*$ zm;jU^o1 zet$i^KmD2Bn}7aA)$Duxe2Y6kL1C9eD=Gk06_0BidWtX()av+v)Me^ zr2E@>PA$#m(g5JEhuwTA@lQ=Vwssb5Nyi4jISRWpUBUR<;TG-B_f9)G;Re7t4!d9N z>~g@(m+lKU0G1}~@|<0D!d%)(d(r@4IXb)W1Qh_vHBbTo{)e#pGN>z+0HElw`xxV4 zL@V$BD7dqWx_Xs94^;zzV#6+bS$!M5O`k?OJOGL_S~!1NeI1SC`|w4(T1Tvh)l}vLEBP*=Mqb^!Zz5zSq00000NkvXXu0mjfj@&?m literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/green/right_01.png b/spec/test_app/public/images/buttons/green/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..7faa92f14295b59d1ad103b8f1e71c8d611f092d GIT binary patch literal 412 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 N002ovPDHLkV1kB5C#nDd literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/right_01.png b/spec/test_app/public/images/buttons/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..6593e136c4e83a3067da3ac2f9c178da3123e629 GIT binary patch literal 397 zcmV;80doF{P)B{;oD9e?45I5gQB{?w>pFs=HvqcoM5bvX6Nl@%A_xNQ zq9}G{St=Ob>qN3FBUvO^+i9ALwr#hN%867WYlUHmFgxhd2Jw9#n+>@d`9`m{fPC#E z)@+E@B*IIJ6JZbr;bQ+2kfv#@0C^IYh(Q>HK^TNV805c$DDoiYJ24{cKVJ~kizC%MRV*I3L#28K;Gu>A68cV>1} zk|bLqG9<``VfcnWbX|9?l-kVmIt;@T5@vnh8*A+vuxmiS0@(7rO4GEIrfl1`R8qbk3oSPli+Ak=3gSjo2h%1R@A(yUD^d8Sw0DT#20~9j1e9eUi+*^QiWy8It;Xg!z tuXbyDyLHRMtivYRRmG1 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/buttons/top-shine.png b/spec/test_app/public/images/buttons/top-shine.png new file mode 100644 index 0000000000000000000000000000000000000000..76178087d322964981c6b5a1cab4c8751df7aefd GIT binary patch literal 819 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7PpWt8vl5FMyO}iEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-;Pr3NIKM7BB-5f)5db^5IHAe4@1&O#S<_HJO3I zk)45y8DR!M%mH}>5)2=nN?XA!fP~V8w)__`?|{_3ce0md zhFVTha3UN;bPN!og$D6XgsliAkU&G>qolUGcbIq>3LhH3X3cE61k42tp00i_>zopr E0Lzctp#T5? literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/calendar_date_select/calendar.gif b/spec/test_app/public/images/calendar_date_select/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..6b7b7ca96eeb500ed1daff8d970f9e30482ff637 GIT binary patch literal 581 zcmZ?wbhEHb6krfwc;?OU|KG2lKYy-VxpL{!rC)x0*|>4z&tE@Rty;Ba&6>4q*RDVL zYR}D2`)_|*y7|!TYk$r@`?cx9>&#_$A{#d5ta;Rb>f7`SKLcx4EMLC7eC4h6XI~a9 zzkT@br+^9PH=ccU;J|_AeQzghyT5V$y5OdL&08L=J@e|!lkW=_ELgX0okP*q&fU+e zHa_k?@Ve#1kL=B_^A=p~Iq)iJ#>I|3FI@YsMD(3H^7K#2>Zel242OrO7u$_nH{Gu^UAw{Z=+V71?AJYCy?*tqiRt>$8(yE^d4Kr)^QgPW8F3Hh oE37_30#W4OIX)@#Rr%ecnF|?iOkVejQIwhnD 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

-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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/cart-empty_x32.png b/spec/test_app/public/images/cart-empty_x32.png new file mode 100644 index 0000000000000000000000000000000000000000..0f2b511cc128b2fc5e0d5600d0446b372d6fd31a GIT binary patch literal 2035 zcmV87&No~h*L+iTUD0bSJw$tfLAKHg@n8aN?h9+?# zlb9HpU{-_e0tN#%i;w{AD+aFC+yBMHO>G&c(}{g%&glNGuFn0=cmCfZN)QC{Fb7Q@ z@?h)g>bB?R=KjR%_GDPC*0*eS+Xb3o2*+^`#(-En@liY>XiCc~h(yYj>$0=!-feE` z@pwFo59A2a)6+G{WReJkB46JAc-}X^^-|NR)6Hj$Mw9YE7{KJ^VbHHsMTtPR;yKu*Sq)bd!_ZmHsPJW{PkxHwD3g_>dqTq z*}Cn~ef!@WC@C(Acs%amK)|0&BoaX(DFhSABu@mv2~Hw<9W+hxAGEeQ78Vy`2lV-%F8pXMFT9r$7G>&#!(I4uwVwjK3r-H5!d44w)UCnsrKh;U--57QVcf?w8OTV{5%6=HkW=cr3Z{AQ$fS=U;fKz z%$K`e-l)xHZFjrfeU+7u)H5tAxZN&`%jp!k0ZiO3=f^IWtIu3k-hd-W1cQO|PN%cA zyu9K!;wgj2oK8m*__*i_zt1;fFc{LFe)_3xDN}JY8nb)6p3z7oDwoM+>R>3;*WcgU zqD)h9sx*}*7zljIEI2I~46dNjX`tG^3tgQp zDwT@64->Ewt{(2{>g>cdwaz2m-535LS17{JBug`t2S9y(GA%`xRwtIR2?(|Pi zObkOb#AdS%wzjskAkH}iyJlu)rmwa2pQ%{7&h6l4F)x6X;H%(9aAaj=RUeDT5=y0# zT%VY*P#a~b{XeREW9znUzgH-f&`WH^v#$P%M>f~P`rFX}J_aT(w`<7lbe;nr08{JS z4n73t!6P2GyJyRm$LdWcQ=BfBp#1TmzS3{v$NK|wzjh^kw}E& zBhk;Y^cK&ygPZ^J{p|U+wzfZF*Q=rMl741-`ij@&VzT12z8#&uA11&ZACKW*H0eX(T2CatRN^p9_b=j8rNi5|-_HyRq@T zl*Q&EAL?}aXN!u8h!U<7n^-8Bh;bf^MsIaB>l_7(&5g+7j7B41fxv1a zRx13|IyX1ld+P6hJJ8qL2(do`m31&I!*^ILPLJ0erU>N+J0`}*L!v>qd%{#N7YonVzP@7*$4PfVd>xH{{?iLH zGt==eq$y2x(~y^+v!$k{9{x@a4-GZLo!e1(Sa^b#ou?Bj-@lCCF~!aCogTL2bZ!#$!mQ1XGe~ z0ntztq{!M^36aE5baD*_a^uEz%g>J;slBfUkanlLyDsd=$k0B4#n8l1={l|MwX!m^ zO6-uZxMXttns1foKZwSn^qo7G%M_asDbExZ7J_M{W(OG@80bby{@s0BvQ$H((Nw(j z?eC7()I3I`LXwjwPZGP`K78i=_o`9r?|S~3XKTMxQd)X?=Z+o7C7GnDxrto4e7UjX zyyXXHfs)Z=1S60Ly&et!H3EJgZ?j5BPj@##k3eorPLh@7 z<(2XM4n~H=YW1(O!E*+Cfq~?@j?da(E z-2FSka|@KO#yMMY{??8DS#we;h1UEDQH1eiVua^;znGlvTK8f9J^!}=0|4w;Fpasl RC=CDr002ovPDHLkV1oKn-7x?F literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/cart-full.png b/spec/test_app/public/images/cart-full.png new file mode 100644 index 0000000000000000000000000000000000000000..6d9f2dce05de913a417c899f1d813c729bafb191 GIT binary patch literal 4074 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 c@IL_t0MU(8op z*`!+xa1VR#91O$2(hIqFPWHa{@Rl8DY^Zm>^Y^m3@7!CPI(_T^Qt)IubX~`N4H7_f z3B{>TPyC^!W%WT4KyyAHIB;M~I2`^-GM)%UqtVwUrzSsQIS!&I;`P^GM|XEOvLkQ3 zT}V&uDduKZ)ZVfTSf=q`eoJ2Le-;F}5>-`Uy!_h}j||?Jzvx&%(~Wm^!wN>$tcBnb z*HqTlzWDd!$Id4biCd{u$~hyONrm$939!6tdF?C{oVyy{s@3#rI{a+cIzQ8bNl!yp zq0C=LCVm5F&z|>Py&hk5f#2^BnzYHHU7NOSUFG$9j_up`)WzqXd3u+j>jis}p)2&N zf~CJ@`5OxSYahcW6Giwu67u=Hqj9NJc7)J04b?TRX!7aMvV)K$m-*RVeqv(c8G+{y z_FcK+Q8e|>n|roBxxHuG_DDy^TH1JNQ2+ymrqf~C3Igab84g3&`cYjOLNb*km$NA3 z@?coT5r8xx-~qa>Epa1%^lyJX8VCeVa2zM3)9HnV#->!hP}u(LbI&~<3WXd2bhTut zr93!6{|rw{J#DJQK>K`xCFU$kKW_19*)AennFirR)$qm0bE05jVWIfhhs&2PUf9~R zt-NmC`d1p78owF6Ib~|0P2DcB6{e|!(MvE4`&py|Rg$hq0v1syX^;rGw&spZ1W0?G z9W-|27&fgbu#_UorDAD`0ACz8Z$^g+fFt3$+V$~7atF`zu*5KUPm_%`@B~EO(jo91 z49W={FMu&MaEysZAFXt>Qx%nfXF^p~X!NtO;P!Z-!v!;_;eqbNRxU87lEtqv%lY*C zKm76U_wN1n{$wJ4p|7w1cvn}~YvfFK1wRijuOMly0>ex2b2&()LV*c^6+{I6ez?dA zHdBU7?{bl_q<}4~V|0e6ND|Fp3Jq5M>^L#>i+2>ZlOQ7|ZyfnJg;B0s?#ib4ES!7UAJlNGt(X zu0}(BnCs|>JiDv~np;|$4!!!zPnw$>MOV#hrwU#sOY|(!5@Dkfi}SOP$)!f*iuqz4Bd*R<7lB5>Lv8wD1lth0G zL_Gze5Opje1!`BMWl4lY>m{-RUyczi-=?!Pe*-SgO2U)lXqGqv}=z zml=YUy9Ksk2dq^)z-7i@-J1EFX6Hv~ej04!&P6&u18eqUu&cJis@VuOHwA01m*{P< zDjxvD$%;$h#Q0odd_@b)#$xG_;o*MWFrhEZpgeaKC5rE|C8M02fHF7W&?QrXo}B@5 zla!2#C>kQl@nI;jew4~(lue@Nr=Uz_G^@oJRT25hlfwEXn|s}Xvg#W0Wz_fxjOkt!3t4AwQongel%rYIK%t_}3vwIdoE8yiff z5<@<}ubWGaA|+8CAWOKW2f*iJNY!tFB|iu$pMa0OiR-y)LVqRL>;$3z10-uV0^xQD zsTf@4tI!%Z!3qXY84BRksgu9E8I78E6(Es_>*S|XO-;?+!K%74uR%~aFF|MuJo(n; z^S~6m@Rg_G5d)NSDq!($O3zt{p*HBXjbLOyB#okhY@Mgy&=4Dsh z+xu-PVz-~nV%2fJ$2guVpE-ScHj#{HN!&EivEiYig)cU?%UVFD#PZ~~_Uso$*Ykx! z;mqMb{qY+U6XW;U4&Qw&D?t6KhPn+KH~!piW%~R2j#F2&rK{@!o-9F)g=z8}w?N+v zYtbSr-2*I5*QpL$0bbx)yGx=9J3cu%IkjZna+}-RBW*7nc=0OBaM{II9vfiqoNb8ucxRQJ^hQH{dD(NT3}{odi>nkkM@K@ z6+LtqrESJvSyB1D&dv_6eP5u%g^{7b6lJ=9s+!8)sktn<8*6H+cD1&)IxSi(7Q@Bf z-gB|ot>1jfQupGgU@*9L-&0QyY~1(|OBE7FjvT?%)KvdJ-g>h;lbQe0`dyFh{!V)& za&+&WJ*cj(#TxDZS8t%Q?s?Uqcc%mRrSPOmdl-yj^k}D ztF6_|tyV`{Upm*ikE{0obNoku0RYHrh002ovPDHLkV1lZaf_wk~ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/checkout.png b/spec/test_app/public/images/checkout.png new file mode 100644 index 0000000000000000000000000000000000000000..41dcb703beeb65656d0e1add3dbb95facfd105e1 GIT binary patch literal 794 zcmV+#1LgdQP)) z!zLm|;I)7h+h_UH_ zGN{y1F=eBbI)m7+P-X?_uYGo5fFwYXWiSi_5(#x*F`A~i+(uF4Z*6UV-~<+erUMG; zCUAqK;UfWXg3YBxNNq2}+Ui;k&!z8ZxfKh{t zW8By#fq{=c2g=1$YUc^Evy?TvyShj<3|&A`2tJ38^affaW0ojN4z1ViT}m5%L?eHF zeUoqk_Xjouf>jwso90U6dAWmtFD9Y8;}}WQR1-7n;BF4?Aeg;}bulWFp;}o)r#*)Y zew~|%ID!T#fC)x7)M`Z^4|)h-w}jb3%VN?UK@?-(!ZELdEB{t?p^>6l1U7jpaXiYw z4qSVrL4yLWC+ANosv`1mPLQKY%B9qau%i{gss>hji#^&`YrQWyQ z@pg4{^7;Lu#Ntr_KEuMnVZQ4yXR+$`{9}*DEq1(msnrV$apLj%e8=i1gvMo!#j~@r zXJ%y4002ONxGrzE9%iHbX z>+`V!42A(CDkvo{0Zxjo)zrbs8WgR0;rLAZ)Du^yBxul=A57 zy{^Qjc#Qv(0RH##)YY%BazR`YIFDEyo*_J z^@1StY760heqx%c- z&+7j8^Db?*{qN?-(&_c5a_Od}+q9kk$yc>?Gp@PhwV%u|mCm;-3$~)6`ThT}%;xx+ z72oIcK(6Ed|M-q?VtsyH&(F`$8XEMG0G!qEPH%R|v%{&Nz@uPftD3sDywA12-OoTI z^F|H-oe9Fq=lIITe4x%>q0?=n(#D6B$>8w($Z+t7KjM>&xy0phzvahVOCOlk_N8v4 zo0a76_t@j{A^8LV00000EC2ui0I2{T000R8009UbNU)&6g9sBUT*$DY!-o(fN}Ncs zqQ#3CGiuz(v7^V2AT4gVK(ZuBB`8yxG?^0RN|Onhz*#_q$bto>8gL8IgUdczDVmVb z5XZw58xvF{B*3(()2C3QN+l3-;)ViPvmW?UMu=A-WeOb7dce;kNO&MU`f^}wR;&pv z(Bwdu2%MZex!k}Jbd3fiMs4g-ijZnm!&M<()%xX*7y(ftN4dmEh}Z&;R0Y_~IRG#} zZnMTE!hwcq4h!JubRlYQ-@ite4PKfUabkyy#R|D3pttYejLHD(Onft*w*^L*K5ch( zYre1i0-hq9@Il)jvEN>}_`sbgzr*|g&Q-j8qPNOT(?G478*A51q{p6Jxc2skR}Tmg z&);|X;&`|f*8+6ag;N80!6)BQ^j&8kNPNg3Lm2oK@C9%EjrZS%pe2WpOf=P$nofEB z6x2{f9hDSqFF*hR1_1o&9#1e42p#~5< z@BqLPK+uDLKL}_601GQvXAo5w)NutGNY3yA21Cq%!4v&x!cPQjB+x}20Cdqskwd&N z!xNHP!6ZU~Q~+fO0=-dX7*bUKDWR8M${0{{AAW4;({u`dLi0`P9U^R@s18e{+fDye96ArQa^RWSes^#I_=msP$20Iq3J zIFQ2wxH`bD`^ADyAx60WQb;pi=rYJEgbbofB^`j`1tBW8VM#iDK!b=Ew)D}5Edkn0 z$L2uL0RSDv@Bjo50Qh6N9{y63?uvtQN;sPfI!<@R++HbUg`<}05`sh5&#UJfU1L8iA39pbSB(z!AOQGKD_VIe z4P^Sm9R%?I2{BMY0HzZ*1--{c%u`Eu!J?;(jqDmoFcjDr771(I4Vg<%e%G=)f78AY@5JGl=gz}mf2}SXMQK-}03Gm{%(EY4~C~^qVUiZG)y-j!iz}*aq zK?tK@Y#Z1j8iYtfy$D9|6c)@}&2F}{(2Xu=AHs}OIODz;F6w=7^A`O)Ml!z{16#h3 ziT{k^IH3`)K$Z{#07zoNFoy97mXTS_z8As~mhYh+Qi2GKHp3atZ(?$Tm93QF4r5>h zBgP;Ewz%a0Uw}j+RDp>$B;pa_MUILAu!(9ULlVna#tCK|X2G=A#_)}>gy)NpLzEy% z5<>;DoHe{*hG@CSZNc-M+cFkD-+9ZM*hDhSaD+k|`p|`Tf}$7AXeaz*DN~8Gq@hyh aN?ZEUn9j7OH_hozd-~I$4s}%m0suQ59r79g literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/datepicker/backstripes.gif b/spec/test_app/public/images/datepicker/backstripes.gif new file mode 100644 index 0000000000000000000000000000000000000000..63f14035142b4ba489635a75c9907ed7e5173f51 GIT binary patch literal 234 zcmVMOLc**Mu zTYR$8d#1J<^Y2|?M~-GVoh7Qa4-2odo5u8QJNTUQTE7dzgg&Ch2uzZc$YQ7o%|)G5 z3G-TgVy7s9hQxeut|7Z^A=xTjM{h{y6RJQ$+ijji8tC5N?H1qN_Ps`y0%L6iWqxUD>mzytGdg2sd$SM ktkjD%+*XX0YR-tZb|xz{bJG4g_o*9GqNST$~&{V890g0&u{{ z%)-LP#>T_J!6U@S!zUyHk`WOE%L_s%0VoC6gTnZKfI*OhL79nznNg5|Nsy6Qkn#T! zh6)BoFaWv}1{hhGnK&V$j4&}E&Bz3FumDgw2P4q^KzWFqFk|9HCg#a3q9KNkjf#P+ zf`t)sdG=REXwFh_;TAQ zXY)=|Jzv2yau2kvUJji!pLXA=q# zNMMr@An8Peb^1T51_NnswV^_~Ae`iI1OxVTk@iz-zyHKj>DQM=&A;uNE#Hy+cK&z! zZKZKh#T(PRbV3((i&iW;8m9r`L_X>k{g$!l=sYkl6vz{aSbbDX3&s@#s*HlEgmMC1 zyMU%V>IQN5R)Gx^`|=8#BB1FYML?^Exrgc z9M0AG=-Ra>FliCY7`XHA)rBp;{M1Mzz3ie$yp%lf$F~l zWgLvaYQw6Vj@CNn-Pirk5N-bV)qjRuwfzG3!G7SiRG+}}`U-nl!zb2H3>>U)SQwu$ zTQR)7!ahNpL(%yJ8)F3H0tepT4fzflg7XVB1Q-~2Ua@8fFxNeZPf(vA=di%v&SA|v zmiz`y7L7`Va}Cy|j8C|L1|ca~`+|kx{tmtaL5wb+80S_syt`mlv;A+*{qL*)ZaKGK z;N`df48^~vIr}+ture__FuY-4PwM=^G{IVggMmr?!Kx)p4GiiJxGn*0X1v3|_f~^} z;Q|8(gKdNH0tN=jJB!Q@h;TxcGcbJ9FkxU~;7{Or!MKz`wnMgy#bK2}Lx95nn*d13 B)&>9o literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/datepicker/bullet1.gif b/spec/test_app/public/images/datepicker/bullet1.gif new file mode 100644 index 0000000000000000000000000000000000000000..ae352c2b697b3309d21f667749a7fd4a2d695655 GIT binary patch literal 55 zcmZ?wbhEHb zn7DSR*ytGc7%6$hIB9taREfFC38UEw8fx+>T53van%aq~+G@$_8tVuvTU$tLo9lFKS96bdsUA;tYoh^i|-QC0O9bO|&URQqJ1dhHQ$nKu? M9{(**KT`kzJ6L&uY5)KL literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/datepicker/cal.gif b/spec/test_app/public/images/datepicker/cal.gif new file mode 100644 index 0000000000000000000000000000000000000000..8526cf5d19a915aa8073cf344873c4505491970d GIT binary patch literal 127 zcmZ?wbhEHb6krfwSj51v)Yr?)cd3`J*V1K6uU)?O9}E~67!-f9FfuT(G3WrDe9t*l+9<3>gnm}=;-L@=jZ0;=H=z( z|Ns900000000000A^8LW000~SEC2ui044xi000I5;3ke_X`X1Ru59bRa4gSSZQppV z?|kq7z#uO}EEin3mE$jQpf%+1ct4$;!n)YaD4(GA+$+}+;a z;Njxq;tb~J=;`X~?CtLF?hEqs^!4`l`1$(#`U?L400RmfNU)&6g9Z~QT*$DY!-o(f zN}MPWfyIj$Giuz(v7^V29uJ5dNwTELlPFV*s$9vkrOT8CV#=IJv!>0PICJXES)ixS zpFo2O9ZIyQ(V_&BDqYI7sne%Wqe`7hwJOvBShH%~%C)Q4uVBN99ZUABfU{`Rs$I*r zt=qS7(BTJr4xw7TUm@{kM Q%(=7Y&!9t#P8LghCzcN zM@?uXLl+&i8giB^{i0bsi? zez(w<3jllrzyJVn1^^iV$XxE$o8--fJif_EK9>uSak!rf8Mm8$WjD@k|DrV?hvSpU zJN02dn|(VI9GScq>V)HxxqR-{rwl&MfX~J4lm~CO-{6yRd@gx&lf*YL;BvWSGTFeu z0QXb>kDpWjCrVrJ|Cw6<<$s@m1AKN~C`Ri@&a=v}{$S&KFKZ%f8SV}5>!Jo0V;=Jw zZ(wywnljH+=v_Un2GNPrD<$$0*eSPW9Iz4~sB{(r{+R-EPFG8jO_crn&%^)_o}B8D z>6Dp{Ow9A32t%aJk+2X;x&kuANtPE#iF*Ts2 zBgOB9troB`o5wtmgK}xwU{Kh%hp=1~CtZqe-1#3u{m#&WCS(NiAu~$QvH!%7V6Ttg z8M2`7`T@9x%s~}JzNgA^BwSYiO)lgn7DPU4_8BNUe$TM-4503i(_o8plxmT)DfcuH zD^zA$8VcFI>w1pRD1YI5DCkf}aoQrY-r877PR?pxjTn$*bWM2e7{uj4!TD0TB5ka( z!F;mz;WX(_>IKw2k(K#egBDO~A!3`^+$5x|b*|;e`Z+Viy%pP`hcD-RQBzEju$Yxk z#$h9_MGmedV}YFYL}A*6YnP`Q)|bYM^1vLpk`fd{5=|YBOpY}D$#KVpi`A?>U#dsxx7HiHcNlHQy5Ym0?@13P_EA(^r>0AB@5UA_R ziWF2Oz`lb4X;XPvqxq?PN9**;OaV;5bfFU!|3nC0mTNBTnS!1n`4k1rko~E&8PY*P zMF1YeLHpfBQxqx0@EO`{Ss3VP3W+;VTwSUahn_1>8~Q+ngo0n@NND)xTx9`a-Vbun zWxJ-bIEpX_(Fb|x`**Vg>1Cn-d7c(q^!!V0AOWRO7v66BmEmp9o1wQ+1A-d52!g0a z|9x96M*E|ib!3jtP9PMD{8~pEB)It@&@~hW3l%)TKxq4DhO}BG-dt?)jH>0E-x*D* zO>A4{$WdFry)I$2exc*>nKHp&>s#L?j&*lz)!R{78zHd`#Un$pPz36(;{FVa>`^D1tgNR2-7Wzzn)>>y^A z&OqB#A;ROv6iMYPZo2pK_*NxxdvI&60dXj%;eN#u>Qf(UX}g-qxy9dJs0PP37|hSN z{1@5lOR<#xr9-tVJ>P{+*FRIw`7&GgX{ocisv6xozEm8fGahv|KCt9@nVWjAbH>iE zy&t7DyEck1=>G8!EXgi<`%4plZ?(bbFM4_S*THyxB+Rpo*9!Whmu`GjxzLMY84}KO zaguLbxf)dcgYFA-w7KMtgP=Eu~H2I;7%NXo^G2*jc(D+XJOEJ9Ac8fNW#I_f5BvoW$ zn36ZXWq2YhWcn~1{o-$#ei1+}mIvq=^9U-dUL3KfPo+Bf+>B_;3WbeleSg$bpcc)5 zY`iKS@$7nr8rNB255p0!SxAt99Z@(RrH7a~2NTaAKYiripBf1WT>Lem??52&sw^T39V%|?f+p2}#p zk6sNcIxctRbVnpq_HTBEugX1iRT|c~-pOHJ%iFxi-#-1Mi`SJ-Z;PvMu_QO~9LXw_ zW&a0GYIhw>706T4E8<#eyOg5rY0}y}(5U@zHa}67W>!dhT|D|D1Fwpb(GGoT9>%Op zGoIJ{%XXOfb_FKY$UYb{_nJs{cAV3qyO8JcciZRb$-$q``UN`OM?}(b&87laPYZDu zMXG09Amu*dEo=J~By@x>GxA)W)xK7*Q595s=tyzo z!nc3ZyH{>h_7+LBYBDs-DB_kM_a-|ZYdf39!LqvZ-8;LZTB-}99=5 zGry2AZC-onoo{Q$lg~??1c{yqUu@8{2w!{;ne3()Ip99iUDu{KqO*8YD!eObRzOWg z|KsSYw|Wx^FHc~^EqzZA>nXx(&b%yX`Ti(%K-a`1#UomOvs|XPg6J?a1{EG`b667# zQMYY&DjMjR92p1rslWGxEXO1dE)axB?`0}vI&=4QvTqV6^D*$`1Yfb=(|S}$Gib2Mra$l+!`78upuI^zRz4)Y-ixU){M>hFvM6cpTT40isUEj7>A$CTwDC4klZH>jvA_uc zm_tHEJpo7uHJs{!pLJh*Kiu8Iut>Ihj>&iTR~1>}y2|?&y$bi3EHF$`*RJ+>Bm1T! z1Oko8N>CYe8$vdRmHChu3xm=@u!7|dDI@mgrMLe;KYz;jru|P;^q3u4iq#0gCxn&I zxJkc9H7I_(meQBy-A-+Kc$fm-p55wCwGHE-Lb_rDOkoJ#4|4YI2UR{9d+>P40cG~8 z;A!6UQPGo464}?opJ-vx?=HYEjE5DOP-c}bMh~vJT)VQmJB?X3Jt*-qL0qc~c2qE? zJ9VfU6%Ne1+QbY?vON>(ZT28~(#9hli%+XGc?Yy7O9ILy({^3sN zQhxiX@nap){qtSRvy~@#_G=qY-ko1bS$3HaKO4=l7@Eko;q|LDm_kO1S6iK)DSr z1<%~X^wgl##FWaylc_d9MNXbBjv*DdlD6bOSeuZLkdeN?_Ju{j|CN(iPwik{@;EbR zA>RqUWB>pEH@+Zjz|=fNiMe5+^QP9tg%(on&DMO3Ogs$ctr|6F0v!5*rZITB`njxg HN@xNApLH~{ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/favicon.ico b/spec/test_app/public/images/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..b5b89e356350d751adb54939fc1e52a98e5c808a GIT binary patch literal 1150 zcmZQzU<5(|0R|wcz>vYhz#zuJz@P!dKp~(AL>x#lFaYJy!T_TAGflYamD&JI%Z^5I#l z>sNP0;Zlz-etl{BoIUwG|KHs?Vgr&p-RE$8e?HgWZ?EsmqpQWn|NQcn+T)W;68`-9 z!3L6lckj5>v$Lziv8lx-c4ud2&G`j!tIy63-+Xpf=vEN>;^LI0pPpXP#-<)w?EQn& zraOxS{=@LDLVh^=@`~&^$ZD~%udXSc0@8bb-=xAHpI(W4d;e7O)6>h^2O6~=@2Qaf z4B}(c_wC(dnOE0#dF-uLczd8$>E+KaZ-xH+{loa_$5$bc`a7Fy+Ck<%I5;g2oBqRX z#y4SZzO}Zr52R+ojRUhI56pUd=fiWOPp|K(?91o+e{zb~L2UXTA77Mob#>wNI~%Gx zKfHUa)O&T;LQonE+S&6z^5CqucVFMLcywY>(zCOx2*$(l=Qo1F_D=p6 z79Cr7zTougli2LVCidy)cm6luK1r^-d$JUyAH;tA`K=l@wfMwV+&)?tzi-N`AHRQr z(=k4^*yMIUzLZpXV%gE(fBrCIlLv|Yvu9xVA4j zXY=FSKa(n@6aY}N>d~9Wi`SRC~8OGu5WZfcdQ}+6d88=TiZG4YSjRs*s!}0RYa479RTHqT^Dps92>#}pyaS?+cs*$ zm;jU^o1 zet$i^KmD2Bn}7aA)$Duxe2Y6kL1C9eD=Gk06_0BidWtX()av+v)Me^ zr2E@>PA$#m(g5JEhuwTA@lQ=Vwssb5Nyi4jISRWpUBUR<;TG-B_f9)G;Re7t4!d9N z>~g@(m+lKU0G1}~@|<0D!d%)(d(r@4IXb)W1Qh_vHBbTo{)e#pGN>z+0HElw`xxV4 zL@V$BD7dqWx_Xs94^;zzV#6+bS$!M5O`k?OJOGL_S~!1NeI1SC`|w4(T1Tvh)l}vLEBP*=Mqb^!Zz5zSq00000NkvXXu0mjfj@&?m literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/green/right_01.png b/spec/test_app/public/images/green/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..7faa92f14295b59d1ad103b8f1e71c8d611f092d GIT binary patch literal 412 zcmV;N0b~A&P);_=3k(2E=Z2)_rKo^lwd7oO$K3c!5m=Fg+mSe#Xt%E`~MGv zwx$NitW2<%f0N;5bimEU4WbOd27+v$6fiP@DSohlzktrBYC8Nw1uvr*`1|i~D!cIi zpTX|s|G%gmhE#UpUuuWpuYXjI<$wSGQrEyopC3}mC=M{m#6V>*YT&4W!_C0I)HCoG zBZz!NH3R>>2OGGOItKn^WMF#324YPImo^j`_8I7&r>sCHG86+_UymT=;af)14f@W+ z!1$e+f$;~^4rm*36TCcRdd5DB47XhX;^RPrE}%;Q1Q-CEAkLoLD85es0000!3HEX<>xE|QY^(zo*^7SP{WbZ0pxQQctjR6 zFmQbUVMeDlCNqG7G9|7NCBgY=CFO}lsSJ)O`AMk?Zka`?<@rU~#R|^B#xt(DF$2|k zc)B=-cyuP$eEj#lzKxOL5tEL~%H%~Gtu@#d^DPnSv6>KM@XEpK;0k6FVdQ&MBb@06Zo?vj6}9 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/left_01.png b/spec/test_app/public/images/left_01.png new file mode 100755 index 0000000000000000000000000000000000000000..ae846e4ebd07e13b8f2ef5597f76576f6d5444d9 GIT binary patch literal 536 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 BVZZT5cL_*$OW!m|J^ucM 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/noimage/mini.jpg b/spec/test_app/public/images/noimage/mini.jpg new file mode 100644 index 0000000000000000000000000000000000000000..3538aa630d12718c262e4fa61718cf8893d3c2cd GIT binary patch literal 2013 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/noimage/small.jpg b/spec/test_app/public/images/noimage/small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b636e84a71ed01c962428710e7fa2f8b49c50fc1 GIT binary patch literal 5175 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/orange/left_03.png b/spec/test_app/public/images/orange/left_03.png new file mode 100755 index 0000000000000000000000000000000000000000..c9bb3a66f21187b0d0010dc4e60c3d2496e424e4 GIT binary patch literal 1885 zcmV-j2cr0iP)m9j1-Eh2jSJBt3dY2wo#VXtW^&)1bI!e!L?y%bqpx}I&CI=b&OP^hckY=< zSVU-PX^9fdm9Hnu*8~9o000M!$?DC@%1UEnDT1$;KL)2~k3PJ-_yF~|2a5p!064f} z7m3_pC~|L}dt`C>{CPTj;yzdk002OD#I6*&_ZDZ5UjE><7wPtsBaz!&hot}j0CYp_ zN}+rEvAgfM{Qjj^XtIBVWaCd*2mk=Ufro<|RL-6}a_HNSFI}Ym^b9Nm005wqS9XJU zmd{XsYKrJDT+sml0O+3BEiBGVy?pxADF__^0D#Vl-G!$gyo-1XH=+Ol0O+pRJ@e?j z$B8!9U=aWS0G$=PxnqaQx48Qf002OT#qM~Y3y2*60Dw-5-2_AE0001VTK06^>j0001p9RL6T z0I>rA0090IvHN{ZCSVN!005n&di3C@>vHR{+i3Xr?0EYhNwrJ)hWVe*933qgHH2kV z@2heoDwNC5!uqjRnc=a-f3t%psb`VjeXf^Z*2EAZH@;FJHF)FIy$JfAt?hgr(FqqSmnh& zob6vxzq@s4=bWf7Hx9M3jpOeW#YVM{6XaP#oOiOCJ6&>+aPaTG1^HOh%Qj`PG+`(7J}V%1x{XT5#i z``qpObza1I^+?OU*pK7e*r2vG@1y-VuYbIKB^60M|H+BOP8nIYX4{6l?Z=eu)OPbO z{i{Wrt+=q~bKR%?CAW`rViE7IKFRPkuPm<}lHn(^TN|@KPSx_ceZM(lv=X~7zme(Z zAD3TotqTAEpmS7W_r=#YW3~)$k{*a6WYT$dbzMRd4{;{R{oZZJa3qTY4|IVnhRH#>zq9DSROGmzin+}%jXrp z&aE#ur8oFWNq=yP)RaX*dw;=U4DfITDpehCo*BP34cQ;5wv;L^?jE z$P~3?UphH0G5VN|?eTdO@#pFQt>}FM%i`Bs|_9;dl?< zheD{u?IN07g}y0l-#nP|wUO`CVmH#ED<9psf3P+&K~MF5rk=!s!npg$3W7|DL~LLv zZO}?AVr*k!a9%7Qp+kolSV~-sW)d>(-~WFMyDr~jxbo`LH6V97P~#MIHFkD( zV4Cs&-HZPjhy-7sKV;aob0Hm*!45VTnAyI}2#pw*@(gM{$LrakjWc+tx3(;Oi2jAbnVMv;^gyGqj zpC&-=S%{Z^eq$gPb8>MpRJj>}%+7>a!UC400O)9HGU$q2Ouqc)TQ`tQkjQ+#p{r?Ep{R6W1{ug6d`d1bt(ueF5mfx^s15ZBqlg%pz zc80ls6&UXP=a~rPHUVAt4ms3Ve!*PzA1Q$T!vr95@Bgzgd}L&0IP*`CVgG+ohJOr< ziLu{rEJvVEMpydDn N002ovPDHLkV1kB5C#nDd literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/progress.gif b/spec/test_app/public/images/progress.gif new file mode 100644 index 0000000000000000000000000000000000000000..e0deaaaf35b6c8786872118d5506465c0b19f507 GIT binary patch literal 3208 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/right_01.png b/spec/test_app/public/images/right_01.png new file mode 100755 index 0000000000000000000000000000000000000000..6593e136c4e83a3067da3ac2f9c178da3123e629 GIT binary patch literal 397 zcmV;80doF{P)B{;oD9e?45I5gQB{?w>pFs=HvqcoM5bvX6Nl@%A_xNQ zq9}G{St=Ob>qN3FBUvO^+i9ALwr#hN%867WYlUHmFgxhd2Jw9#n+>@d`9`m{fPC#E z)@+E@B*IIJ6JZbr;bQ+2kfv#@0C^IYh(Q>HK^TNV805c$DDoiYJ24{cKVJ~kizC%MRV*I3L#28K;Gu>A68cV>1} zk|bLqG9<``VfcnWbX|9?l-kVmIt;@T5@vnh8*A+vuxmiS0@(7rO4GEIrfl1`R8qbk3oSPli+Ak=3gSjo2h%1R@A(yUD^d8Sw0DT#20~9j1e9eUi+*^QiWy8It;Xg!z tuXbyDyLHRMtivDSr z1<%~X^wgl##FWaylc_d9Mb@4!jv*DdlJ-@9*Ar%DW|lEFGFtSZQ}pn0^{_svHwTm0 zb|yBop8xUvef*aX>3_bzmv6iA|Ns9)355d;@~lEf-`q?01RBHO>FVdQ&MBb@0EMMC Ar2qf` literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/shadow_top.png b/spec/test_app/public/images/shadow_top.png new file mode 100755 index 0000000000000000000000000000000000000000..53fc5f5b54110c7bd561dd68e55d9b8d1d18e5e5 GIT binary patch literal 406 zcmeAS@N?(olHy`uVBq!ia0y~yVAKJ!Q#jawqzxnQ0U#w=;u=vBoS#-wo>-L1;Fyx1 zl&avFo0y&&l$w}QS$Hzl2B^!z)5S5Q;?|ox8+i{X@VGi!8}R;qpMImEjjc#Mm9cC6 zb2UjpWd^+q*Td&A?l}0IlcAM$!3GE+B9^d$VNMGJ7q>wKgP#*nP(ueu00q?*8xAoA zL;wk}j6))$gbq*;s8K`=Cf15{P2>@Kpuz%{`f<~f11ylRfq}t7VfCLi zj6l^AIzWd2-P+6wCV+CyAph`ye99x%aF7X1+?dJ4!=P-UB|by=CO0sk89ZJ6T-G@y GGywo_<#GT3 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/spinner.gif b/spec/test_app/public/images/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..274b4fdb1e8ce5c0a5f766934c02452b4e13bac4 GIT binary patch literal 1608 zcmcJP{ZA8j9LKNiUAbPbL4sOIr(05(n$niuAq8qFQYM)^8PG5X2#e3N zrLBdIhgx-(Nwf%?Yzx_wS;9|(gkdtK;GWE;namJJ!Xn}ik}SHbCJS@^y3arG`n=ws zcRqB1-IP;JKm_yyfad1rZr!>yJ3BixG}PAC1^_58FQ1&8Y;SMx@9(E+y1u@Cette2 z4o9QW<>lo&ckV1LEyd&Ug@uK&v9amt>D#w&udJ+$j*c!aF81~HJ$(3ZczF2o<;x=@ zBTt?@dGzSf(`N(yKcjytEY5eATJxOw8?%i(4olImzz7Bb$dDi=G$H;c=7^KzdN&8J zH?4&?tkcnVmzU79z&Qr(CCy3Gb%H~o%>nTM@nL9dtRz%*-+_w?>G7Dyl%mveQ4Drl z++0e{vD-<3-XV9|wE}_Hld4c?A}A_Sp3|z;njVfkTBz*qQ7Xi|ZG{R-f$PdBQp%O5 zrhb_w>l@}Q{=kCDk<-#qp4S`(luN2Ufe&K-G7%k z(v;OgSSIcTb;JgeK{D5lDp26Fe4phGeGo=#uQVXYr>MV?$Wr?3HYEuagoD2^Z*F!2 znZ|1)HCnAI;0GGDx-;O0q)}Uvz}w~BWj*(Pd>~NjUByfUm<)+ori*2o%y`e$V7}iN z$}Y|*y;_MU&+_7P9{1Vtj;ZvO+}s#M>pxatxS9Svl7b=E?FtW&h-i%>)uj^$U7g|g zT#7Ikvi5YH4!d8jwmqS?kP%|^^jR}1@eML_vE0`>8(bG8q6@)4^B+s>TTY0Me?e4} zogJ+nxiWYEfb}H3k3hw|qdkF*It6t^!=&8p|y=Mw1XRFk5{)jQ7B?~22dN=);oCkzL^q7i|VM43Y ztvPrM=rM$HFkC?6LXHS&uB{?XuSza)qQ3D_VZehFK>dlEdKHchPDoiKw(ySXz@XmdYO-#eUFX4+b41WHb ztJMaZf;dyVCK79vJNf)K>}nyO1Qd{VFnkQaJ9hS3FwIUl3jCH;Fo+c*p1~^35#zXo z>X{mBsi@37{~hG68+LS&juRVCGp7FZ^ola-B;|v3m|%-HP#Ya4Ad+iAr$R;q98SXW zRkAdDDguKpAmTSNB*q28BSJ-iUTP7=R^KiGd~TO$NV?$}@LFT;`5UnAkGqOwsxH%6 zM_@=D-Cli!L{0>BT(6G%UyQ4yCdJ#LWHWsIZ(A_C8vpL% zB}KU9+he}*j}Rd$EG#M}Dj_B&AtNRxCIbU8nfWe~|H%NHyO5*+WD4y?AygowBmyOg z;BEQ2p$9q$%EwO=M&&X ziQoWJ62-Gb3d3u<-dkEFd?%JqCh_78GgUQN$9q0FJ;ttjbAI)t4P!kYDNKF2ONG0a zTAXn5wXD9(!Y^oW?xlVz+H?O^MBisCjguLBZ=QP4_}BQA;)hLdCpP*;?mL}X@~HXU zB*EInKWcw+R%uO3|CA(zL;`JjxH|Fk@#=F`Sb~w_0UCs>Nb_QMCd$AX+;glS!>Rf7 zFm@%GZ;+)h^**Ze!3yv%)vs;1jUPO;Q?U^J>9oBn)~17$e+++SVT zbAX+?TP|emzS8n^v{9g8q0OVb7egeT_RuNUm^)<;T?bR?c^eX)iDh`=>&fd*pFFGG zBS#`4X&V#n|HXUo@Tb6<-f%3`cbvaw(&$R#x`2n__Y&MCOwdwp#u;t5iqkUdE>=(} zv0Lg2ORL@+6$Ra*l)aD7?DKBpK!Kl79xmn0rC*z@G0$n#qgRhVx*Y(eBwoJk^~OH9 z1B<&`N7GfbDyS#wreWf3*!GNqBgkbtwzXAFpKdlsn@Xu(5mTNnb(-B08Z%eF_moRU zce?;31UlYOueX^#dc(bXh**~S=%uH!t#I&-guLgSx$38jk4>5Nf6|Q4N}b!7*OirH z^}6CUWtsyOaiHxk?3IVht2Uh9dD1+b1Fe1e(&%VqSN*i(N!98#FLyR@pxo)MH%=Nx zXt4`vcL;2+^7x#QjHI=45o$@~D8_vJh+~|Y86h?s z9{aG^I;(1WRg2`S%BM3ke(zS%aCuuQx*lu1sfeHSQ*M1<-Ns&-ve|!>NDRfkeVZCH zRJCECgw(9tzTc?!v|vaaJ$LRP2WocNs+pK=_Jyi-cJbWu6M{P*%8$+#_VeTjRG z-bbbJ&j@p%dmO00c<@W?260>#A=}~WBc|w{Q~^BfMgN%fZVz$$1v$fp8ab@@s;3So>`$94yV&TmO9={NU=ZpYPi zxXp^?Rp8Hs+%Mo)dB^W%7b3Dhet8}T+Ne#R@tl~s(-Uu3d%a^wK{K=FOyrZ+Nm5s8 z@xya2D<>}JdYo$cteM|(sLem)Zi|FURej`aKY_939_huV43nOT@aEYw>b2GKeWx)R z39s(Q#C;xqqN7|*Zx-P|H|lRM>#2OyvB@b-vgZ_4Kz-MEvsCOMMEG8J0#%m?4OHg02c!Ol(>y^|x3+elUYf)P(tCRYHlc;i_ zcl$>=cQ=n$?tjO=T_OJ2(2KEFJSeuxrkw+c-WWBn8i=XtHs;ii7+u#p(tK-d=)v~G zr;{x&7H_$6f6z@Qd}a{`vNYa!j}-l>u0OabE&k3!rNhxhB2KKrU7OyeZJoSaujs+^ zBG|K`1$uYOl;6SBbA8iX*~F3fYnxkGGgOsiQz0`CadWu18w!(r zl>KpEC|MsS@GF&BPfQLqx_OPJyx%3Z@Az!=U`nb^e)%<%h0aYSqie#dd*7Ai%{EUH za#NMF+YU}F$T^7K9Cj)FXx^3*4Ei0DypmIs29z}B*iT!#-eXwGZZ{Ua zWE0|nVHSeCCR^6v(!hysa8rZ3? za);tKVXoe!WtNpcN)ss9c#{LUK0jQ-f#kmy*T3Y$7-u{!&ZBHkiFLU>ci1I8)_u5O zz{9Srx4`4JqT6t4VN2X_PnYF$$6*ip)miFL$c2c-Sg~ZM1yfR+j{10jP+qT)mKeAV-=1Z=W zQRB|WU)L3mIu8dA^*gew5?e6W+59##N$%5ypA0AUk1RTHB|rA|;;B%-*`by%^>@oV z7TdC4yVv@cov!g~D-Evu6xC8JUuzcjK=qzfbi#sK`+-XiCwo?Bx-(FF!e(wLU$Mtc zSYI2DOE^QLJLEs31xNM?y>8*F`+Gw|A@_EpB@iw(!;1a;>}_ z!PEroRON7dQfJzO_k|KC3&W(*%hp=g&k1$t;*Nxe@01F8q}nnkeVGFhR)T%vK-Z%< z(9X7@$q9|73FF-1m?Ssy3ZuWK=aQAb#J0~hu8K=2o#X#d#c7yucC9rXj?LUX*m=Jy zqHiihd1`{HcCv3mJf{McWAkY&r9A=f!Y0&B47FEH2WxPkMasD`rL-profACq{T0vh z$*ZZ4c?BgWHic6RQg)9s%k51D6&3eZ7%LW&s+GNy4ZE6)r_=6~4mZcQ#}!eJQ&Z}X zb+KEgI8b-~jTq6r&+}eTqKHV>H)@kXpS&l8hdtN%XP-LKTrwTy310Cbv=NlFc=X2t#^yO@-ErdAC{a zbXjNb#x81L4-Z8-$gO%QCcAI-P0{+>102X%`qHe|V1-!jioy3xH|Fj)p1r+m7Fp%H zl9$wID=k`WSgx^awYwAX_Jm_UyQY!0vnfB)uK2d{l6PKIv9?=tpIgm`nN_E5umqPZ zT)VV)%_rN-3x$sJKYuu2?6l3;>_&@s@o2?JE3LRawInK(_VN*7V6L~NBdYpDhTigQA!!-)r3>>(`>b@p^X38 zgVV+tkrw(HzTvcWA)*=Cjt36_~`yw=brqElZA4LS6P`C|rcN;T()1x%y1NCcEsOKN!{b^;03I8H*9z8+G?}m8tf&O25I5YNw~qqcM3DiQ zUk}`bK%59cdqEX~LLfTi52_dB2L(bj$Qw|&;{y15fkWi)1?~%v@mu*-;5*}+l5mq2 z5dseldk~)wJ%Z-TwD$?3fY!HujuaLKw7AaZ1hNMqbecbCbBit2kM(QYj71Oq*5<0= z=pXQ%539z<3<;!AnHxiFnV^OEZ601O50Irm<>xlY7Qc+m@6Vt|g#AY1qcZ~i18G!R zL@4MZVz~hx-JVMWZBg$C7TuakqcXf%R9`@VoVJEhzX=P?3&RwcLk{&vgUA2r^`jyf zAx@T?oWNAyj0+q8cZwa;pZXhx&pU+W04f+sWw8E6eB*cW@8ZHf{^s-$I^!4P zO3sgOX8nT!xMzX8ZQ3K^%u5DySdD?X z|0JCLB%J;voc<)7{v@3KB%J;voc<)7{v@3KB%J==PdLp-O-tY?3EB!O0uGbpL2AJl zq$GSGDujj{pa6igKxJ~VFhH{eNeU_y3Mvh7;23}Lf4dJF!b94SEy&}W}u@(V`_WDM;o*$^iZ8>?=T&VwyqAe+BiDQn-WZAp?#&m z9q4PQ;-YV-YZqot4G3JbjX~Y8ZJiTkTQG&>t72?~UL9=^9U2x&WqG5cLqljxgJ?q) z?%)OhhsioBXs!q=*ieOg%mBT~&H-&sXHe04+88a0E=C`X(Z=c#F#39$Xr~A&+BCu+ zjm4tD!3sPYi!;Cw46q~>FcZVq&%n{b>f1b^WvKFPK~Ygr+EF-dI>TQFLn4uMbg?>E ztQL^aVs53eyrZ>fOx5orSWuZ1Mqn5#kWNFxBYK0}4a-mkXgROGcbJ{skAeTzQlX*n znz+(TmLv728h@GKqiE{PG5=+_1ke2 zuzi>x8ijp7t@5MGZ(99ebNBrF1gt>6f3XUf^P4CYoW=S3p<&K7}X^=C)I zf6&puoIwQ{D+^E!Rp3)OTDmwbEZ*t+sT?g`Jp)}`?i>bobl*U~t^b)Q@L^wXmiK=o z%vAy8bUefgymwbhI`@lP%5h7!n?@h1JIVD!3+)$)Yp1!afdfrvb?HfnD*2KLLg+ zK$1(`1bb*m#5@tF%Pl$>`0-6(^S=}L$#T z1eK(T#bY(G1U*mzji{%okJAMe18_hm;xw@&ye3W;qlv>1K_zMGV?o7X0S$~p&;=F9 z65zHz;Dd_O!(msMo9pXhusFOf24{r@-eyiT(={`*A`s0;7M5msuxQv@4IBcasUe#z z0)dw@=dFPQCjQCV{0j@O|Bb`lj}72e3GDuTpx@Vs!xQm(ntHkg#eLSS7&08UX}WA%Kq(7Xo>JlVC^$k^sVU z;eZ8U2+x88mW3hc3m~^Iu&W+M4{%`!v;}aULg3;=7?OaV0CHtW`T!?jVLAcq0f1nq z^f2Hf%!P1Y5)tl8BEm8xA}m89ab-vtE)I`I;*Lfl!84M$W0GJ^u(}w$CfH3)-~pO= zO@by-lcWhugTZKGu$ma0CPq&a>@E<(5Hx`+V1X=f5a1ucb@YK30Ve?d0^DE~hNNd{ zZfrFQ8w(kiL_^w;YWA_-Zvm|0#bg@W%pwEbzwye=P9F0{{P6 z;Ae17rGbb%3WVOAUXe{82Jmulw6`MLT5@v@B5P~|X>_Cn1clOA3^*v*wAmHS{{oy+ z5CjJ%z8H3giUh+v?Za1@5t`bQ`JA9wsktzY!e1W6kzg9;K7 z=#9Y30%`tWyJ^0G+!RtE?YFr5ml6Jl-F_JXM(6z+AkrCgkc^i$BvB^=p+;&U9%*3+ z<(>vOh#&iAE4UHl7a_<+xqsg80S@?F_!~ebfF_a|$UVISnL9e6DG`jwc@ZA?!3&O3 zi9<5bLP!Zxg_c2D5Eddps~{7Qt6U4&Lr&0U$P=P~3}z_AfTE!7&`xL{bQn4gor2Cn z=}-og4dp|HP$_f=x(7XioNM&SDj!vjszJR%b)(*+zVh(#Nb{h1w0KtWtl@Fy zq40$B#PJ;AIm>gEr-bJL&nuoDo-v*|UQyn~yeoMPc*(q*c>Q^!c=z$1=FQ|S=6%T9 z#QTQyQMRvA46cwyqg(uJK0JPIom)+85$Hg&=FE6fLJfWzhXssBgct-KQ;(H}IB@?9}rISjPN`uPM%0|k8$|sep zl!wr=Xj60uItBdzJ+@@=k~K>rmRwx&V#&0MhKjSwE|mh6PE{dQqN<-Nxc#F#rlzcB zr?y=!SM9aBpgK`KKs{N#Mty3j#!{E1`MQY`0^=Qj! z+iLI9F4g{^qo(7klc-apGpDPs8={+`+m4aKti|lYlw&?&S70gFbJ#|lD9#EOkGqBY zsJBv&s+XqMsxPf?r@vpnT7MQ#z%%gq_(6giVGH3rp@k?zbRZrfJ|^*!%t-O1JEX4$ zcmtL}p~2`XtyRIRa#jtj)>utlow2&lP{q*O@SnDEo4P9g`7BaQZOGX$>15`V;MDHC%sIlj zdZYM8_l?;br(7&tl3cns>1>MK^lY=j=D^LjT=`u$x@NjgxLLZLa(nBp@4nBy*+au4 z+T)3*f@g?lg_pROw^z{?-YqU$a<&N{ehgX@lpZt{Y#*Ez%n5M`DF_t^-4a?xlcELF z9?+HO(e(PTm0|nBy2A~^Plb;$Y#5nL1k;0gizNg8n5vCf7O^*?C( zlF_v2+N~?L9^Bf$&1&0~7@inPO!f99+jnm7i8YPA7>9`SiK~uRjo%ahc8B$jt2>2u z2Jd{nOLte&uJPS2yUX_|?%A=YZ?E;<+0#Z&rw`8@p&WU76mvA?DCd~pu@?#WgtX&)$7#o#6O9wECP^l3OX@peccSDZ`sAUL z0`#Wv;E8MQOV&&-?+INNm2>|DY5#pe&6pGx&jZAddo%THHK zKb+3K5O|^WqV>g+OG_`EzRY(y^76ZkjTtpph*z>R6*3QJ&SufFy01E3eUMGa&dyn! zlaPzdjmRCm=6>yEo<-iRe69S81#$(4uS3@(t`FVVa-+G>rm(t*Sd@QL{pR^%>Ec5r zh?1=(W2FJ5-M2R1sxMnxR$acTy!f{E?W{XX?wqTTtw^X8s@zk_soGXGaX0Ml`+NTP z`l`LE+wX6>-}qqtgBK5N9zK3#_2_<$X-(B*!^d}?7(6L^N_<-S4F9a8R=>9Rx&HIw z7x)(?b%eTGFG(-U>sQxTHW)YDdu8$JQ6stWS<||v`ex_m))x1c?pEK{fwqvgkFO(N zPq**r;O#inDbacQ&Ehwgx|VkpbmO}#dMtWsdpGp9_fh(W|6=|%^LEcW(RZi&mHV>? zumg7ntp;BXxedJ?4jZ0+zi&ixL z-b{v0PEQ^Bvhd5*uf(r4Y!`O_bkq$0Ov>!?+44D?xeiV!IOP3zH-e?W1zrg;SqTYQ zC22`%B~=AkSp`*<1#nUMPcHN#WTd6#7RoJJuwc=j8^QlK-w6I7MOHhRas1ljoKn6M zItF}4-LD&zHuK;3P;(zGH!!`m%=C+A3hjv z{h+RndX0*|HM->Du~n^6idD~BGgoI9r0Cb+b^bchPTkg<6yDb;*`G0Y!f(_+`-Wp~ zwy$BnvHu(SkL#HpgGrx@=3f03I$o6u?$YMGF{$X;vv2p}v@Y_h4$Csk@fEXyY1NB* z4zs-)mR;gqk4TG(6jXl39_ee`9knfG3g?Ze35ezy;XtO;s>*BYPuab#E)(;m2cLaM zx?Q=yu=xhnwLkRnY2KJeU}(5dsd@K% z(K+*lY(0(f_k@mT&+X)zqx44>*(P+gkGCv(we8JD;obgCmn+t-7XPw<1MT+6TX@pz z5H^?9=;~qks4KID1Fg3tuH}zEH@;hY_3_8}uklvo$|@Q6+ro_PDj*BVAeve%|*91bhozV7Ij&e8x5#LMR6 zK==&#=rt48O_|sHiKp0V(fairb=A)v)l6jPA4x_c@@_rvyg5rK8qamfD#QfGT%{Qn z1mH18MW(>@*-hYb)wWY@$Xd4!&tODtcvHJSrL|wvsNfv6bM2J=Uzq&XRy6_tffKQ1 zYpr-@D)aSgG%1q0Itj0;r=DmdcQzIp3cVXOxr51HRDmgbGaCQWwbQ?#;`AzM!FF@Q zf?Gkp@w>BtZ(RsG2TAHopFGmH=kacZcJ`=a(&zs5O}xsqu$wMu_LWBwY#p{|!E89o zLpZmx!{!C0|NUKJ>sHNGmFb^m584PK?@12?I=oN|c+gkn6rDPrES}ziW9E$yXy;$@ zK22E%8H+Zwa(i{n`(vb zV_wHpIi?eon+w{<+jF;bpyTI|&l~v^6*s>&Gn8z)nF#F?IL<=nFCgUiyEJ}MJ{m4N zswHCd&fM5?23)JWnh{qLVR%CpHQjCt?%F;-sg~ue$3q8_$6T9+F<`Y8-NnuMIxhuS=v@&&7CM>@C&Fc6NJk;{>JVfd4xV)P6XF z{VFDSuriVDvYIbpY22v~?pZcN+Jj#yXk6nW8~3($GzZc$ii>k`ekP{XIK3jf{J~ss zeC(*%dJS~qS9Ho_5kJ-bbMZr;pDTyd8e1J&SM@Bs(=C2XJ$0w)vlp4W3$A{wVppvj zWefXX?VEc#p!rZ^{Hr}*gYgNrHEyoBBj-h*)3@2RY$f(9-R*_5qhFtW z-u+Oy^W#^K7kLv0&qVi2OO@&;?C3X8+c_tcbEd-SY0d4d@e-GSHd^qMVMV)#D!55H zR~D6XbDO7^UC~u%Yr6;IPm+y>W9xzy2yy$FBW)GR!;!1H64seplw`?OJ>Faz%z^6i zB+=^fhobGV3`Ng#uK{4eq8a>-_D6XK($~ynOdt@I)ci&AW zrE~nvG`J0qS(qs0Uv0a8(B>~Ufinm(v`V~{@hbYHTfA@Fi_Wj-qBxMw*RBn7Z^!`| zx#7>M27$Nld)=Ktub<>VcjGw?A0$%k2Mt|kOQL35624eCC2cU*xIErb7125(zPhZk zCO&;*=g|I{SA$GkNHk3n+!k*BM6PBmlDb)~5vFj@sBIyUSv-k5Tr zXu0yo(=YH4;?3Z!wAftYQBP;aY-MJ5WJP9I!z}RfB>`K;8J*DkP z1L{RTxx+Ump5#UrQ+19@d(yKYV#x973wG5jrY62(-))cF^v&(Jz=t7?-JC;4T3u*3 zz;CAYVz6@oe-^QFNB^dtn-%@x?bB5$4=+q&Ml_?vg7=Uz)}XV2n-`%t~-iCR{NCI)Ok@jthp zYe=xOV}PrXo&hr>P>teG7FKo!4h9{NdXTXUEcyZq1I}qWE=v3@c{x#r;ehNE#vZo= zp^O3%tF}jdjNxV6oixqSv*lJrlT;V0awn1*j0}uGqd0(ONC|kRs3|Sv@(kE;qLD|z zqwCsr#o2;uf>=ES5mq9U%L^zv_f28yF}iqCRLP?;al(rfmKp9H*CKfiRLCCbbV2B0 z0$RZawn9>%w{rq#f`lZKkSJ5gfesnP7rfUPSZ2GpVpA8c!Mn84oN~ zyrvi$?$+dLp0PM23CVDTas>g;%03e&)<7Pq@P?A9Dh!7iQan;cW_?#&ufSDgsfeP9 o3FuQcU~ozb$g&);I6k9kmjm+w-;NKS9*I+9S0ySoxG`7*0L$@%+W-In literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/spree/spinner.gif b/spec/test_app/public/images/spree/spinner.gif new file mode 100644 index 0000000000000000000000000000000000000000..e24bb172c45a51c115bd9b7f38a116a7111798e7 GIT binary patch literal 1105 zcmZ?wbhEHb6krfw00PDT+}*|4<~;zESM2BJDuaISkis-yy@XtN~uYAR5yNmuXt@feEw0oXw zb7oJxVo)NSd)s2qec2n$?ZJT@Ej&WaF@Cd7swYl}ahiGc+2NZz#ga*|6J@bm%Uz<+8>BmBi zpa8kz7|0dsidVmJFo9hmXV`H0)HX@ag>yw%&U2>ko~tkZBxvn$^-yYJhEz&4RahR5Do(($7|ya4w$X>bzSHznm>|hxa9HtZ#uAlIri0CuB~FVkJ>$`y8@Px%$^3M}l7G#S>0}(~ciZ@Q_fE_gOhb O>xy6NL% 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 k#B5xnGj3_G zxDPZE87Tf_0dsXgB*;z%)`JN~0!#_>GFGk2dA+Yd=X^=-{j3c<9-aRWEGY2Mc~-*S za_B^k)%*+L3A}*y*TU5yO+Wzj$~<`s1>Aa>%MR-&vb3yc&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-_xtai)odcWYXcuX#v&**e`rEY6N?zm+@Fv#zb1OPjf Cv`g&( literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/step-progress/current-first.gif b/spec/test_app/public/images/step-progress/current-first.gif new file mode 100644 index 0000000000000000000000000000000000000000..9aef49ab2b1dd6bd0679d93635a05d88d2e92f99 GIT binary patch literal 148 zcmV;F0Biq8Nk%w1VaNa&0HOc@0G8SL{r-5z>lL5ea>eQ!q1_mu-FwOFA^8LV00000 zEC2ui0LTCs000A77+28#Fv>}*y*TU5yO+Wzj$~<`s5PW)>%MR-&vb3yc&_h!@BhG{ za7Zi~kI1BQ$!t2G(5Q4uty-_xtai)odcWYXcuX#v&**e`rEY6N?zkmDFv#zb1OPjf C(?^N` literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/step-progress/current-incomplete.gif b/spec/test_app/public/images/step-progress/current-incomplete.gif new file mode 100644 index 0000000000000000000000000000000000000000..09722285f43994ee150b7e4be672e5b45a4b4129 GIT binary patch literal 319 zcmZ?wbhEHbJi#EraD;*3?%lf#({A3ocklb3f1f^mO4#@O%a<>H+n#>?`qh8?({I23 z{r~?zao_X8qpu!6eth`Zw_kt%CGC6Be(vq>zyF>-efr_UhqrIvUU~bI0S8e0$pV(q z0g)g(8Cdru7)dZC%*$A{F6Z^W0-f_Ex%aaQcsx4)A6QV}q4TVyYhK~W9IN^38%mb9 zM6JJ}-PBPsX+yyE6aDg}dtBZ@Is^rm@MXE><|cxwFf- zHHep6w0qKI?cN}MZjmXoCr@J(=jNNUxO18ix7dgsr;e3* z$F2jVd3*OCJQkHFxP9aCv$Zit&YZjK7Q?ge(v@2+jMtCee&E7*@!?aKC(m9wC^A?B E0M?hDhX4Qo literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/step-progress/current-right.gif b/spec/test_app/public/images/step-progress/current-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..a2c652d5caccb7605cd21f8810903410aa8a9dc7 GIT binary patch literal 131 zcmZ?wbhEHb6kw2G*v!DdFzqJ)oZF?xUP&yt`}6O=qNA^*7v7aybhqO8YoH`1Q2faP z7SsWeATtSumB O*f5?8P;g;jum%9$L@Db4 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/step-progress/incomplete-incomplete.gif b/spec/test_app/public/images/step-progress/incomplete-incomplete.gif new file mode 100644 index 0000000000000000000000000000000000000000..9637b7f3fad6a753d4fcdff6b78aaee9c73cb7d4 GIT binary patch literal 278 zcmZ?wbhEHbJi#EraD;*3?%lih?%n(M@87FeuReYH^!4l47cX8sfByW-moNYS|9}7f z{nMvUA3uKl=FOWAA3nT&`}XJ0pWnZKXCN9V{$v5G)d7(pI~iCfFHlrqOqiFkYF*Cj zeFZw_OLFhORuoZv_y53x0*{oJ6-Sp8oy8a5NfpdYED4imW=@?x vYu@Z>Gv+Ujp0jAlir{4{*MzQKyTNz;#x1U!x9)J*zH^V+?!5<$6d9}m@bQIN literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/step-progress/incomplete-right.gif b/spec/test_app/public/images/step-progress/incomplete-right.gif new file mode 100644 index 0000000000000000000000000000000000000000..ae59e235de25c4ce6469dce78459cff67935f4c6 GIT binary patch literal 108 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 P00000NkvXXu0mjf`&GMS literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/steps/3.png b/spec/test_app/public/images/steps/3.png new file mode 100644 index 0000000000000000000000000000000000000000..e884e3e4dc5895462574f8bc246fbe512e8648ac GIT binary patch literal 6184 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 D0KqiC literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/steps/4.png b/spec/test_app/public/images/steps/4.png new file mode 100644 index 0000000000000000000000000000000000000000..3134b5e58ab8619fd62f7711f96734a47160a2d0 GIT binary patch literal 2338 zcmV+-3ElRIP)0P8B!uGQIcgj z4J_M=Q>%3YC+?~ZvWOD&vntR<8+1_=O0wv(bYdl~wJ#Y$AnITA~hae%RjwJGix(jM) z1Ik;ApjUS`acb)93va#^3jqs%dE*kgtG(IB2L~R18kE$ru9A-G&I)WS{S!$kQ6^j- zdvR(r3;{}*55ND>>tlE#6a4IB7lAVlT4l%F#+U|1b>~QePTB1gPbC9GqhEoI#lKGK zwflWJ%sE44z`YNDezoV=$%($}!=xC~e-~ zeDWK=9NI4d`(B3P34SCieW0rqQ+7(5pJ0F2l%a02-HipP?5tYSi%KrZgLnV*)5(@B zLmy56o8VkFKbUhJ)N-L~*YMTdWt5^5mTIJcarK!92;hT;hJ_Z5bCn3`S^^BcjDXY@ z92{!_Vsoke1Yr8Nc?Ld%z9Vb0r7EB1{d49sKP1Z$bLx)3wzaT5ZuLfn;;Q9r$bD z5`Y%K&Nz^rtI=2@Qi z4ukx;=RjNhsAcyPW*Hi*C9|ik2(AfBZf*{4-n?mUo5Mc&m6a7|j<#RK&-M$U8vwwu!=n4Ak*RP}9FziwKxS0_M$g z6Zki7+%V5^=gvH=t*zAnkb53_eMeq`ypdMdcHWqw;J=?!TzRu>H4k{(F$lQ|Iy?k8 znoki3b?|FR;@X$HRyB_HL(`ah?$N0oZNi}ARzciCgiCJlxf9iUYqBfqy{Nh~!n2!S z7PJzB4wax9Fp^JHy5*%gl0C~&--vdWOM6CpS4$8CtpPq6(2ynIA*W%?Bg3F0CCI-9 z@WvY8*_XR(0QV`p+$}rJx-TSXF9Mos0NZn2?#+_MdES^Q5n<5zt03@sj>EZ64e%~c zxldhb%#=eZK@htHF&}OBMz@o^Zx5z4Tp3r_)ZK+Ue7$VR(4hnJbk_4P$$s*Iv8qoafnRzY62y=bQGkw`DRJ zv(NNO+%+Ix391zCLI0C4I^)sN(WX8TVw2+D?%ij6y#Bkb1iTHt_c-@_WjWv75>#FP z7`7L#L;u)wk$<*Ud;lA_KIm=td9j(@p64c!Ubn$OP3kebg2niArBnS{0AS6ggkZ3}JganBuBuGe*XhMR71c@dj zNJx-qLV|<@i6#i>jv62&s4FvIWb6X;9LomUx460l#g#=tKr7qvGhcx0$f-d4GR)Gg z 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 JPDHLkV1n^rovHu; literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/steps/5_small.png b/spec/test_app/public/images/steps/5_small.png new file mode 100644 index 0000000000000000000000000000000000000000..2c24d434175c5b773653e3cba40d3dd81e2a21f1 GIT binary patch literal 1133 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/sxsw-ribbon-v1.png b/spec/test_app/public/images/sxsw-ribbon-v1.png new file mode 100644 index 0000000000000000000000000000000000000000..03fcbf26cbb8725bfa1845afa0e46f0cc15a8edf GIT binary patch literal 4864 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tab_bottom.gif b/spec/test_app/public/images/tab_bottom.gif new file mode 100644 index 0000000000000000000000000000000000000000..da70aafb44d74df9b3bb16ef5d9ab6b801322990 GIT binary patch literal 43 scmZ?wbhEHbWMp7uXkcJCbLI>K1B2pE79h#MpaUX6G7L;iE{qJ;0JlH}UjP6A literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tile-header.png b/spec/test_app/public/images/tile-header.png new file mode 100644 index 0000000000000000000000000000000000000000..8365cf3e2c71b44b73ef4c9f521e693a9258c847 GIT binary patch literal 153 zcmeAS@N?(olHy`uVBq!ia0vp^j6fXE!2~3ieYT1OQj#UE5hcO-X(i=}MX3yqDfvmM z3ZA)%>8U}fi7AzZCsS>JimW|d978H@CH?yTUS61)nOW-J`7i(N6*vA*kW&06ug5NU z`1t?+Br`4f%W@^w93MB{?DXcDKKn%jBNGq9j+^?u)eFO$fyOX+y85}Sb4q9e08s-n A@c;k- literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tile-slider.png b/spec/test_app/public/images/tile-slider.png new file mode 100644 index 0000000000000000000000000000000000000000..6ab3f9590926aa4db3c8ffb70f8ade5408d6dced GIT binary patch literal 193 zcmeAS@N?(olHy`uVBq!ia0vp^j6jsZ!31PU{$~3DqDovNN`mv#O3D+9QW+dm@{>{( zJaZG%Q-e|yQz{EjrrH1%C40I!hE&{obM_!tgMtL}1IvkB_tqbOmAlxfM6$|LU{A^C z4-dz(o_E?Oe%ZPD_ip8{ qWm9|St$F6AeO=mi@2}T_2@F{q+?&>ZOZX48j=|H_&t;ucLK6VHUQCq$ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/top-shine.png b/spec/test_app/public/images/top-shine.png new file mode 100644 index 0000000000000000000000000000000000000000..76178087d322964981c6b5a1cab4c8751df7aefd GIT binary patch literal 819 zcmeAS@N?(olHy`uVBq!ia0y~yVEh7PpWt8vl5FMyO}iEBhjaDG}zd16s2gJVj5 zQmTSyZen_BP-;Pr3NIKM7BB-5f)5db^5IHAe4@1&O#S<_HJO3I zk)45y8DR!M%mH}>5)2=nN?XA!fP~V8w)__`?|{_3ce0md zhFVTha3UN;bPN!og$D6XgsliAkU&G>qolUGcbIq>3LhH3X3cE61k42tp00i_>zopr E0Lzctp#T5? literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tree-nav-icons/bullet.gif b/spec/test_app/public/images/tree-nav-icons/bullet.gif new file mode 100644 index 0000000000000000000000000000000000000000..6305baea0d4abcf93396243e8f8964c5c392ed0a GIT binary patch literal 62 zcmZ?wbhEHb6lM@+XkcUjf_LxUDgI;uG8q|kKzxu41CwY^|H{*E`4`XGqSv6wW_6pt L?U9EQD}yxv$P^G% literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tree-nav-icons/minus.gif b/spec/test_app/public/images/tree-nav-icons/minus.gif new file mode 100644 index 0000000000000000000000000000000000000000..154e45a5ee2baa0bd114ee01417a3c595e13a7b4 GIT binary patch literal 87 zcmZ?wbhEHb6lM@+n8?iV|NsAnh6V-(hIjAYDgI<(WME)s&;fFRvce1uOd50gSDt>$ rpUk}_OuXTqLc+dE;T4@eYD+S|Pkc6Mr|u7}Yr0Q=o%`<0$Y2cs-bNsJ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tree-nav-icons/plus.gif b/spec/test_app/public/images/tree-nav-icons/plus.gif new file mode 100644 index 0000000000000000000000000000000000000000..93d2ade3d4e3ee96950d68dfd0f5b5ce496ed07f GIT binary patch literal 89 zcmZ?wbhEHb6lM@+n8?iV|NsAnh6V-(hIjAYDgI<(WME)s&;fFRvce1uOj>jLSDt>$ tpUk}_OuXTq!UNr$dn{e^8y4MN-g@gq%39AN{j|tS=f3~5*I;0<1^_HKAv6F0 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/tree-nav-icons/treeview-loading.gif b/spec/test_app/public/images/tree-nav-icons/treeview-loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..0bbf3bc0c0e5e635553e8d1bf9ceddefbc402396 GIT binary patch literal 2673 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 KHVU#K0029HfgIHU literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/update.png b/spec/test_app/public/images/update.png new file mode 100644 index 0000000000000000000000000000000000000000..4c5a58d45c6bf301f0709a8641f68dee7f249b2f GIT binary patch literal 793 zcmV+!1LpjRP)+uElHX|UzUf#rqJY{vhn$iQXn0PEmDVi;? z^A2QH8Pl05OfF7DWmWbQQDVmg%(&fRkJP)GTpT$36nuPY-97@dnCO>_65+c@P8tYH`-J7XAzWjaQ-3J6%tDc(Lw z5%Db@!`{+5Tsm?O4VA~?cKY-=Hxy0LF$~Le{^TofSPV!5yqTvjOu}K^ryI9f9QuLB zc~qALDT%=^{g@HrItjx%tu9@cWME4VD6t)qB7tHGDZ7O43nO{wlk}bvXVBez3r<_L zzNceJhv{zX0ZWn~FX?NM2nNS)prz^@I_s|B^VG{#0`h>7yO}p)a+QR1jB2WYU`5I5 zl7lu>v}0^`2;=in3PY71qVx6rc$avL(b>0adKpzTEVKfGjFkTsiC=MCKKy{z5ptJTG-1auSir*)1giR~CAP1QhHB5q>OsA6wj@*O|dr)m{gd|C8Qf+I5s+3?I zKD@05%aRr(AM%nlA&ukia37i~+R$Fp1#fvXlENfH@kdBz{uUthfZ&dLQP1-e5!&?` zxqQ}r0X3x_yof!4sASd~k3PFN)Vk50Q5`^(HNUEA5n8%7p1qC@8mXjACeB|}H|=`b z?p0KT=sNkf?#GClP4K_z8%`9}O>^V)!(+V!36ON;;}9kZez^LnxOTn!%lz*IzXcco X5QT6jk`&>T00000NkvXXu0mjfxf*LQ literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/visa_cid.gif b/spec/test_app/public/images/visa_cid.gif new file mode 100644 index 0000000000000000000000000000000000000000..2dc54032462c7f578d53b0bc3ffacdc8600e4843 GIT binary patch literal 10483 zcmWlehdO$oyUhdMz}vHcykqdZ@;TF}!mq1ycG*vT zT|KmXlI$|t>FM*Q<^?00d;4pLhi_Nc&xRGx@BG@B9hMcs?H%ra$thPdu;08Iy!H3**3Yli z^>AaZ#!Zdf_)7~$Ol&8yE-?RdA=QelF2d7>yqfUI?cTcLP zf1>UG{CqLv>BXEU7c;udGJ4H2x{i;J#Sh^y05}UM0{@%;*90Js@ndz5FYD$!|8VM# zZM_eO-@qk~*NQCmQxQyPd4P@3BQoZkI6&J4>q&*nul{v4-gI#$i!}10L{`&5by56nW9d%XGO9y!C3$<-FiS((ltjnP}PlWsZVYqbE)2Ck~{mn z?*+AgU~uTU92|u*(}ADSWx9%tR}B=n;=$@sEDyRBDYl=qY+sx|a~+i#a)aJBeg<4C;nUJyJJD%Y&h{=fwx@%QPE` zYIVgWO{SO}-1qE3Zs|2S0nLw!JUh}KidC+eC5OyRzoe*wQa%HFt0y%B>krWRb)#qw zh^u65Z1^>s1*`1=k6AK*2ue&Q9EXQ89;FH=|zR>P&Ejdh4eJ;5 zi7TqV#`CIj6U2A^52G$80n=Pp>=h+npMOf{OJhOTVna<G=8%>z3iocz z33!#p=QlT2#I297*XPKLe{FouzVx+rkmZ$pLzy4Tmxm)MEG-YFG8DEuXS)RbTZ0lz zzc$Y=$@>>a|0=y#eZ?@7@vuK3<5>RDi-%9Yw2!qt{qp4X+zG$l6vMB0=ulOM(fNKx zA&?3-K54x-Cz18F$FZeZ>2BdKm!^lMEGOg}8R2CC51)mPpL(>HqR{l>wS3mp*|@xQNzY=~`aN4>azHcoXf`-MmoRn;lCbkcd{ z-lI=0(cgDJQhz@G_VLpzk!W#6BLV^;PS(p3XCqMeZ^V;db zOXpV^E(*qi45^&3lp1tc;{rW z%Ct<^nX<1Y>w^;?wjv@kiw{HR+ETTT+tNa!-;N{0ho0Qdvm{N_RSn%5aSM<)k2G5? z#x#$e31oJqFBKFWsJ}dyl4(^kAq6NOrf4P&6;z_vgsLRWY_3Y8QwVT=7Sk-IlK9g# z9ofk)br5a#A*vf~=@Vvc{u=Lnrtc-*XQ4pycZH00e@Av;{t76j*HqN)%cgqgyY{( zNA3#e+LW3O;bw1FoJjV^Cbi?t4Xfa|4nF4-FDH!Uu68&ye*p+wsb`-_TN{ zWLhtfe3dTYET+?pQMF&DRIRSt)X5YWjAMtx8lc($jRK9NyYh*hzLHYu1ICN?-kw3h z5Dyjy6te+d4wMAQqziE(KOi`!9-5=g8k_Kpls=1k%UXeN=4K4rSpt_Aui}teJtUS` z3fL6;SisnNASee9kXiVcdu{yBNxKMr8#=AdR^}NRCTaULTvkK!PL7pXK|EXY&C|66 z>%gF-iS;g-^4FZlen}*=t3N;olqT(di~~La40h}*bLeNwD79F{kpyz312Tr}&`5?O zKVMS?^C?^#94hRmM)(=T<>A&9&oR??nN3RLKS+9D)q9iL%&xZxv5)dJOxws`D{Z!T z7vNoo%kcW&PTr5x!=8TD10xIVW`z!W$~A2JV{Xvg;Z%I7a*u%*YjEP5sGAqyga>K% zg)RgFsb!#~)%KC!YgXFa;}_POK`#{Qczw<@pYcIndb^UvP?nTyQSlAmsIV5H9I6dS z0qEJRSJez8v&X-5EBxwv&4{%hELfHqEucnGQS_0LTLEF4=C5dJI`q`lp#zV!&Y zy52B2h)@h`_pN!y@PeKEb}Gw%Q&QySs4=e|rA>k=@{nv*R^|zY(W#c6x@*`fanJY0cnMp0#!x8Eh`x5}0gUBTG=yEy z1vOqjA%{-gtSZ0(ved{aal*~ocfysZ_H^{JegZo?DFMDf0fVeaD0MP~v?hUqG(4K01hLRbFl~MSX;-n*iuw3SbY$!I(+WpcW>PUrzrA`4bfxOiG0PR|!ck;MczAKgF#G^rZisvpnrFfDp! z^HoaK+g$9g);RflUjIztpDa0}!0>8elE50+? zPJ++`3c!zxK#+*C)<8EAR8WQ#s8$%lHEt5D;ueT$0*^7uu%cubFB6Hk3CwK-(L1nX zZz3il$`Bd#*E>dl308q1Rh))N1H`dLm;@fw+JQw7V`NB|p&b|+1DiTexG#lfP7pzB z#_Dziqw~G=;;$nv#6I!zHcyLXC4sr~(Moh!IA6q2BTR?_lU4?P?-BpQLd?`lfOJZ9W zGFCUl$4FqGCM08>SfUjpLrp%G-T@PxNm>+;9}fjI#XqSr07?_~3T}r!~Nhhm@$m{Fs#_38u7@DMKfg@&i)j z+&?|JhiTW2#&XYYPFXU2%DWFPl!QP%rkxwpm2X-h2+M0s4+IJj$uQ^9rA@E?MoPV2hK*ETZPa~vD zg(i2rjwjlI34%9UYOKIWxC#&xvq6kVjn4IkihMxkU=VE$lf&f-Q;Ssy;Cvbh+Y`^t zh-cS=L5~v<%J~RdxGVr`mW{um31g<`?HPekaQd)Q%1~N-)#xQ*{;1+KNE-*j2#IRS zP_S$imJ&^tl{N&W;Ium)4H=UmNnVZR-y6wr%{=%hPAvhXmOydynNB4@+so(|O_4%W zAk+zVHO()~7hK|ph@${Rs}v)EBcrgzCon7-q92AA%tv2wj;KLJI`Mccs~~HRKu3) zMdZDBk`#-P_xTV46}|+1rui{vM3xFbNHf?g-u4YRU}FGZ0+k+)erYa{5$xv|%h@dI$(Jcdjus7$d4eK7bxPkaNpyCJe8C`A%oA0} zX=;Qxji%b};^@5Ms53g0XHKw&)O2IP;xf&WU(SgTxvWeY75iqz6{zaS`M5#v#M{JV$C9>-QN?*qjgc2%A%|e7cRFh{v8pjH z$r~K>uKOU^;_?>;WnQxpXxoWQJZ>YVYm7%W$VLg%V)R4Hxiewj2^}4`Is{m~Tpg_V zzTVm7bXt0hp6oz0w==ooP$()VKmjB%{4WVi7pdIBBjI1hE4v#bNK3@Z-_4`M^g$v~ zn$q@k6e!|<{KOl2^9A-m6ObW84ZoiVQd`c9)kmVL?`M=nG^X`#RH*&w75-8tXq|q| zIS2VQc|GDu>E#&eeAn5Mu#jlamXr>*Iaxa%2iLc((SIE-j0M;2a&vSe+;-q$xJTYp zxCf4{I2g&u^T$vVt?$()Fyh{)H}Cu8gp_7tts^p=VMU`rVhi!RPUVXW#Gfs33V(V( z3r1iGImx4U_gi{j9OND6Y(}j!k{=dRSY4|syPv9UR>$&1xH9raivcCDVh7~Y`TV8C z9#mF^^Me;-(d3QBp?i_re|k$8)udt~YAMp{%ai0{z{dP>@@VI*z}*);dAD4^u`ktC z-tFuBpcsv~r&Ax)*e0bYHF4rzpC^I$tBaNN^FD{?w7)k9qqkTIu&QMAhY&ztIV3lx z=OqcfTtD_Q_+^Q3t9}R=hK@-cg^4XxmZe5F_(RQnQOr>-!oE?g<}r$!^*%yPr7Y13 ze!1F&oW9=)#}mFWGJl$06t_5(CpJxtRLxiJjaOBsS3Eyx(`QLkBae2tpk);uoEz+C z<_+Kcg_2^PV;eXhio;Z*ABMoDE|DH0+o4$spif4K*)XY?BN7cbxX4L1#sH^sTQ4y} zyR=|Dy)pMsCaR^FCph{_3DGr^vcEB0(iC^}HKM9Hu1z3PIC7j@u~JmIsl*4o;R=c? z=PoT)hP_OG&Icyt97Lm>mU4AwEqPyv}Y5Fs7=!R2c?C6ZHp`X$RR>B>xy*#c=fQx9u zd4mGP(=f^YOrJ8D>w~@N@nF&Kya{b+X0g~dX1s6 zZ%WkfrXarN56wi~sF+_`qgY(MPSj)3(%FVrFxr!fKG(*cw}~rzxLw{PPJG1~41Zn+ zV*DiL1NC9bD<~9$`!5)?T*2f(LBI68e_AIkio4;!=3Wjj+KJR2`^ygof2 z8wiIhJD#Gz+vCLtjfC6#g>(U-Q&dQq3Zeig)gR_h1kyyXCkgi-m(2XR9O?8YdL{dE zy*Ke!%XH;D@wszk5FdTCu`T#_xQ2Bjgo}F4*FybGyy+VC`ch+zQxvs3`g3cv(?R&| zNn(y{6(s;_(_YOS1^9Ph%#`^vw(swUz5o1MP@lH!wJ%u1DOOXn9`wy?#%4nqfWD5J z*K+o-0z;Zjy*3G=}`pzL2 z5H-d8X^^7_v-hCa{oY+`|Dd8V4E9;SV3mRJZ# z6ijlmGXw4|)#>Q9Fn7hPK?FW}t9$(_+)3a;PC0Xeb9;y*wQc>;k)TN5y5TNxU3%w1 zp7ry&<-u^cv9&M@j}zMuVWH39#;ir+y3nwJsQ$8m%*>Tl9`Ob7-G`jwysDy)IPX|%g$Wzl-xEnc*X;+>-`LX};j((cxnf5LJkL$V^L8fXrs1!S@;pllO z0K69PBo7|fP{XC2SBQ2=-Y$uGdHhHmJ5z?{8qLUmUsFfj zX4(0+vMkCmBf-wa@_JcV$X&u~j@zr~XCsp%{MycS>8+E}B8v#y`Wm5gXKe?&(868; zRm0}G1_5wuAKuqK{cwp3m`4}mS(`eUUb8W$(wK~DP(}1X4;!ZVT|_;VH!qLLeHWQG z{EfXtk(=4a#uYTzmNt*(-Egn0!AU6tYlUo7~%?sl!|#gIAOBlNH7=*>0fXQM*JW> zOl-#_kibws}fPGte_ADuk9!Zed>J+&g7Ui)GB7MpeHJKzo9X$%0~merHK;1{YZ4;sy0c z+;{S*kMvj^RZNV`#MSeg^y?CprYhT$YkJlCZknc!wrMqgKCdvWR3xGt&H#YEEQh`Y zAqLrW1m^cIh+s)o9uP;}4;>FhX5X^-nuCdnuny9^JG&su0Y@ya7|=)JPYyHysu$A+ zRLNjHdRaLwva%Qe{{%!n=K!yXA%rkKxxj4Z!{b?a< z+h)lpn@AwOORiOx`|M0gy?NnEOBIWxf13Kw)vpuWuXV2T@f2ZAr?rB=^BNj`g zOL+*(;%^iQ%UsA;yC*D4Rh~#O%$57=#rb6=UaDIhExCQY&uxZf?y0i9HB4Y0;)8amwUtHVQpwle|W7{Vg$+(*+Wom;*vU-^O zAX(Xpuj`H)n$8%Hs&3vWylx>stUF5b$St%t3z0TGG;WOlDZ)mDk2yO^NZ-6H<#YGK zPs0x2*VM5OW$o6-YX+)?*La&7s?Cphl@re2NS0M#7BwI4!!pSwV?}MLHhWn11L?8F zn`e=?EnR)B;w5A`^kOaleEnGLp!(qM@kzr!3-QzVKj|M4rs84ejb!{b^D0 z{Tnw8qOyQ!c&00pByX+_a1}Ex^h~)v>V7)jx#Xen`IDynnm0}2Qas{&pUaA?V@711 zX#z75#>A?Fq4o1KWUB)jcayb?ugT4!`qN2>07+AfId_(uqVcKFNE2$w7|6?%fLrv2-oULV3wLCImKPRA~Ul`srHtzmjd&xq2H&?7=uph>e!x>L%y+sk% zv_2-WcNzmf3ym>~&X;MTs+t!(+0siGpP#KiHcoT4&D4*`VmDWNV0w5rpuTwyHozc@ zjExq$2(5K+-8p^!ura?e04hjuEUCL9!A88iB;E8DlY9wv`LpW0XsRtm=}?B73&6{e z_5>`n+Muo#Q9!|oCA&~5oTJ9-UvIOR&|UY?HZp*FvN7>?ZHli!`L*)L`Lo0k2}wO2 zq;J$}sc1U8Nds+KDZqneXYrBx_Oe&pgk9f{$Pu3PFNtT{jo6KF1#a1Kfqj{74Nuz|L|g>^67+v3ii~ggR>ZnolIlAFD3U zl=OZEM2BS*uEALUb=t=OS;H|)+!;ID36hili%C{4tPam|P!2YUl4@%y9gMu%>x}Ch zDG)z?hP_5erOCuZMJ!-Og0G7~u&`2qta1i;dT~gVB&joVw~*Q9F0y~ZQ!R7XId1KQ zWue~|gRJQ5#0qn|nJ9OL^3f?%I3t;?njje(#BS0@`j9igNWAx7jo~pKy7bBn=h0#A zt4xZYNjNBeDt}V^gt#Tf2z-CDwwA}#)t=oGlQrqk5oq~SLPn~+7{#<66zXQ6U2;HD z_v`SL`V!CD>6{Zfk%v$w8wxJt+ttf9IbQ7z-s$ZAHSUq{sz%at%#qA~uI_fuD!6Xk+=sh@`CIqu)KD_@nGGuGnDPP#`MlWKw9 z0wqH8ZzOP!Bf7KMPq+WDV?=qeym8ZQ5I@uFssfAT$c zdMx4WmVvhaj^&%q=$6a@NTmCclgOM(V{^}SZKz}L#>}gw^WAeIN6DN8<t zcA7pNYW^uU=LR#hH__hu0O9^ySgG%vvu7luYD2c!)pP}C+QoEKstfyiF{~}3~EXZ@4RG}2ls)R#4 zs9R!Bm2!`dYlNPET3-aitbOy#&tV2l{dKwmFUMPLif#$=`-`34I4vB*)^n9TF7DBt zTA@XI8!=SdyRe#2;lsH<4dJ6NF!6RZDs(y7ss5SeiC>DQ$0l6ra`GN+DbMkW1t+dy zYcc7$BsL3)KY#KkAbr*T|JIcLN-GO48l*xqS39mFm0+%eYrw-W6G)z6ama$gHD z`v2%GGPHjD zJg%RE`7(*-qp$@8bcrpFLx)uSPfX)ycqGyNL1^(r>WYo~mJJhmou%yvX{_y+v$Zb1 zL^C(!wX&@Ew(tYkB(>66(DV0mS9DH+pjSHJwo5-oWJcjCXPQ@|U{{^LsjZ$vq(lEa zf^6t+*LLn++2X*Y4IXVG_P-f@HzWg-ZC6$&92qqnTsaFg`T|lWn`!6Is(&xj#HgG# zv%txp2LZj**Q{-+SG#jD2GW#PbHo2;5!$j0b2lWKy!Suoa9IoyHYF5*y6b`GbzW-ReQgvhM)Ll$&AorbbqU2g!sbcUPqLIRh^?Qli7*mwqk55a}|JFUZVY@G5r$v1)9)4DlCg%NhwY5wk zYxxBel8olZ+Ia7r;#-*(drOst9Zx_UGQK6`D>3B96kE`k05=Zd34k}`h$G%XHzhV& zb$~{XCXQ;$`4-#%R^3m$yeRdAYgdO^aIK9>_q?dUksX>dZLP8p{@_1FR zGO6?swHod^mI+ZF()zQnwY0IWmH`BYV=YE$WWPRNQS_{?<0hA!hN~&VM@+dETv*{Z-U!--6h|tLBfv-dY2-u-bR_W1 z+=NeL>c8@1t=sCQ$*C`Vd!?a3N^3G0pSP0q9~9f1)|yM z2Nfc|&4&7fA>e?EB1z*Vm92!Kac1Rzk&=5$9pOx$=-kBWo9ive=vlPv>zw2H1=&~n zay#~Kx0rUY6L^#*KtEt`O94v|j|><)>u!)(pN5pcsXHo&w>9zv5%_}$JiNd%@;fi{ zx>B$kjBrc>YzYV~&YF#GbOq2;tFb!VGg^+nAiuffzVodtjho_UidXnWxKXW&x+yFf zyI?GD>Y!)6TsI?2>Oq-^UYFOK)VDp|0RLGDny5R%%C+L_V^g`O>bN^+!)z%$vlG!~ z9nh}<)H3-PSh*ND3exPrpu+t>v#1$0mr9IDf)DK8@WVnz7WnXOQ)B=$T%ZJW zCoC<0?{mek69xsR&M8u{!TqJm0dNlj%6K=Z_B6p0r{^TD(8*KU#+F^8mY6ew;b3w)zbN%D2S9jcO2}vrQjgP;{C@(O?37;iKC2V*csLvSU?I%;WOfOV@nf=IK zWw!5Hta`zv1^cGXWJ)m>95b1&BRCi&y2z@SLx3Odksl7UFlReG7OJC&2>2Fla`NU( zqu#pl?+gdR>_divk%y_;HDDyq1FziO8u)umwW46%SDs&8kg$gPSm4hTdaGeZtuIyD-H*p-L`{DSyE+)P;b0n$oQ+CKx6CBNZyc#w0Y*qo zBd?u^U}Z%-SHc?Lp~cD#9DU^QYDtzd=2ITe)LM6YmveEdt5v+k1a;n)(e^6;VmGQY zo9bn48O5x#z1!8v^o%mmg}z@voe|;7MTF)cTHMvPIYo6tFaEPy5Bnc46K^&7j1071 z1aCZO^ zgh#m!Y4iTCfj!T;!@;S$q*SzTG&^t|&k#Aa#-6l-DOs@{cfYha(3P~=}ADg$PnfGJ&XWr1KubcpNM|XQC-UqHvAx@8+o;vz__Bkm5KyKNCd+Ja8rq|or z2Hf;~mm1bK#$E(RFvY83yDptlOpeg7Qpa9#cx_ntQtikwS?<-J!6v&qPIoWO-=lM+ z(TK>H;pG%gQcp?@D3mT=tr=L}JyDrO2Ig4TRn(R2AK=5k%P;$H2I5PMaV;e%kvbC+ zkgT^S1N3l%c=( zVK(Tqv-5=VQ`-O0D+vgNUL2gL4%sPlXaJXtKqDmJ5k; zHD$)!v^3t+og947&T=U6%@<+D1xC1h|^(4;&OV1|0Q-p7vZUyI<_Phi?7*yicKe*og@}-VQz9 zUGBjX@8wLkWbZn|&g&)5sX+z{kfGNqC@p!NA)7- zd?n$01rvO{ozPDC>*6R=)m?G*6L7ZSe6pOqle76T^mu0=^e8R#NcD6Rf4+Hf{GI1~ zM1^8`p!zEn4B+~&q}n@|dCvkdC-Adz+q3bG^ES*$+r^o6;<>-<*+%0@9{GxU&u>*8 z*NaH^@EzOZGt9*q=D0@nq^9GTDgEN-GL{nnEeJu~I;flx4DQKrf=FTXkYVq~pR{J4 z$8;RVT^98qG~{n|98ZLvOREf8@eNVu@4PdhMuPxTwKs&NLSqt zMpdCE5a=&16Co!@v(7DcrjqSxu!K*#C8#h=XdW3hH|d=Mb47J9OE zqKY|U`Wyr`SFunpCk8fG5p!~P^J~U#?9icTR8$#@AJGDn4@0vaNd(c2bnIl~PuE(2 zwpP;BLQnyRYqLDN*8r>t-AoF4U|KCx3^NxTWw)%uUR%MTF1mXeF#Yu$;*Vm(G&F1m zu$VT?ZRCdHFp(QxTlWmGa_v2AtqoO<;lq-$U`+lLZ9#v ztC01I*v)p{2t$&fmP^QV)K%1??66@bc8WhbbmnM1^!TmC72MP=ziRNek)HGmzTpyl z+RV7?5QCt7$*w&^1O$qRXHfufW?ofI^Z-eZshP`Cy^qQ8LL*{buFo{kv?=3e?9aGaYs56k)@Ok0 zh!}va4pT)l&x}4$`98Z)cK{C-#J__!69L%!Egl;{cHF(K`w3TnbY$7L+;+`XZPmB8 zTW?#u8)S_2S?UV-T8O>6?>qo-H32|3Io)U4T@3PR1PUu0WSlG6hyd5+75z|MVLuiTQkkPa71yQ-a#c(eXMzl^Y z*@*4${z)g)oaiAtFk0+Vo+PW}ZX zdi_{3R?LM4YfjAPOgTa^F(GN0(4rJq$n=f`+Z0b4sezb99ae;eT7TkrK)3tToYO7- z8Od&^^xoi2xVT_yj!yqg%|8HQgv5izTu3%$RC0fZ{2;aIRpN}Yn9z3?06M=~gnM^J z;tg ztn}q#R0Pu@Y%b`V#Rv)KdDFB-bvtl|U=O1R=kf-WHXhioeTkQ)4pkLgT07wFly>wd zHyHY(bI6fNvDrko^(}6j`8oh#{dnxnI^_?^C@8XwB(ke&Iv|)@uZvVcNs8l zs!}y_A58rM!S0d(BPmEvv(fRMmEd)n+A#9TG@Wq%O~CJ`%Eennx)ook zM%?Hg6&~1X#D2lLF6BJ&ffsA8a;^L^SJ_n4^ZL|WG5S=e!#%5W zgRmPr1g}(jceCp`pfr;BX!U|vpQbkBZ+!U8*L&*EPdD{z`TXe+>UI=dz}9sNYM7{8 z*p^5$m3bo_?XU;er*EaenDEr4$iB);kE+*n_zx;7b()xCUPc`V}J_ z0?VfXb!)fX=Otpm!2uRK*ws!(BIaQdIX7!FOW?->85^Hj>-Q|I1IV}jC+{_lW!l_p zbfeOTrJG;H$(jJW`!?`go+STuCGcUpl2IXgV=X7aWAxNpOkJg7BYCJ%H{0c)+sLFN zV@K{R!}zr+r;lJBjs20mG7!M2liB=T(sPNZk)?7}`>1{A`;7?6ek1u7T}F^aK(2adJ`WH(9klNbBE#b+Dau`ofaMaX7;{Fv!|86K)P{&Y9V|>dIA4 zaPB#<9&<8)MM31bI$m8gh!>Ru zaKU0k-Z;v%`EE6-QoS#qBo?sG51=HJ~U|a#C z6u9QL25@aKjdyO(1G8TGkOgC4nCUHwqgP%oJ`_&6@TVR3ZTbqRK<+;;zbg9J^2gq$ zfTlhVmjx1I1k0&iGIx9mkM4p7V#S}x2P1~ad}G~lU8qs-a&$^E7IC6Qs6*EJMStg8Ej0sxhqc^E#KA&3WVlKL3jX2Kj0Mu01#dj9} z)RVSogDlQ}g+ALGjIKvek6eYt^mE@Kk4No5*~gfdUJt6i#e=5im%3%ETtjthAK(oH ztkNc^yvfTLKsiB~&ja2=27|z6A~(W}1$8y|F~S`6^x!t=Zd>cG)#OLbZmG##0v9V5 zIVZSK1ut*80oWFo*tRTZnwHVG1kZ?<4T#Jo!RCfhEA%Yp&1)5oQkyQe1awx7W&d0E zVCrdWN$nYtUw!NoXG&E<#H`4bGRnoq|7hl1_~1Wm*EYglbwY$VB2izGc8e%cZYU%p z>}56Mfl7{#sUw9vpz*_tvHU3~?vNDRU0+gIe%SiRO@y&K{>yVC9w81wHxZu5*!um1 z?hO_!N_}sCVr~qFH-1k~XRHP)t=!?v9}&r*p~4hNBUr<|#_VEnmq?F$`C0+2zyj<# z;>e#AeH}c}4gn~^@~g(O`YBh!RT?RB;7S0Rmy9r!kvQSPAm>@wo;Bw90SG5nbmRSdq+mmBGCUf$B;RKBU0F>_GR9u z#I5k&jYAyeD~bz33v)xc;_|&wocZq;iX%aH`eNm#&q; zPfx=t?6k8D6Ft4BBA-7J7Y_}b@_Da69~5ar5EzivpUp|bnYLVh^w^I$>I%$dz!o$X zpfN5-4YcXTKv>m8OMf?2suNJspu9>ijS>z6qUjJ2a=asYNnXkCJDt+mNPF2#fTwdf);Bvj6N}VH3QaE zr$oT%`Q_tk?uoRBmdUc{4uW$dZj)ezu{OM*E=mvI9>#!=0Dw5VS$N}o@{w|*IL7Og z830C1!S8diZjzPJcT|1sC=n*jW$4%VrfMR@PEcXMPtVz*9)uuh6<7xKC(2W;RKtQm z!Y`*@1zu;zLC8VIvv!hfsP#u{1tY?x`su8YK;ox2T96{z7UM1Xdg#Sor!BDZj-!_# zS^!+dzE%etu4gf`BH^PF&kfl-B217;(kOO2dgP}BN-*=}W-!`Wcjlvb1ZxaPD)!;2^TmN{d>ZuRgEYD5Ifi_3Owf&4dmbvzl9cCgtuSq z9E5r8n5v5d!w14k{^KPJDQdVUN(sXhgfnMT?mRp_j;EyK^ahZB>WWr2{vx)SU+#YK z3v-+d?lCoY0Z#!Y`)_xKDavx)=R~;3;U-ce`zI59mi&eANi>SWV&FXi0E-P1q`1HL zM=5aJdPH*I)-f5U0M8cpKNAKJ`6QoT8QLSfmT-}%w_M97Vc^}-EAN@TXD*R?e4s1nKB^XKhOo=|y_OE2AW~qmq3GEL zPJL;cXEzrZ!TSnd*GeC3+v6X1L2dqE0}eB*@Qa5^=AlC? zsx~~m)V+6bWD>dB2U%lt)nI}^1c!N&LuHN^uT>xYx@Y-Rf5nH>e^*t3`aCFa5Dam! zr}ozHx_Zf_2Z=CAV#Ji|&FTn!;zJZ@b9U(nt^Ovk-ZKVLA4jlL!RI@RZ zzd~yUb$&&@{72Wt*knm7kK$$D??v7w4GCLC^IMsyU+KJ*pp7CZN$Zrn(Q+bXic(Ll zurmSCYIIzr?r}quXp*QfFhs?&#)DYnjE=$V167kBis(Qh_ETc|Fv+!oS0ITWn+-piK@PeM6NBhwIl&b=Rr07M%Jy2rN@G!_^ZTjJ3EioBIm4VM)14T^CU`d4%$q=bSz zEsyU+{U+Ewya*;_zo&a{H#A(QU)FPEL=j34sD<8=A^2@NJ8N#&Cn8{_-_x3^qM%f? z_Nl(&v4sH-ho%w1R%LJBGA&Y9KH32Q-jcxhUmA;_k>64=Q2oi-4b4s8i09Xs55X+8 z^McQVZQ3!oiu2-{*2oOT7$uTz8T#khtw#_T?4*YY-dd3hU6FuQ5SuR4MaPCEk9r&i zgNB4Pgzc~q`w=5bffF(q(uItTU)|#lJ6%TtA>Rx?zvQe)e5nHPyE?KBDE>>`*t=Q` z8t)=#<1N9e;xY}9hqZDj8<#$KjNu0sD2O(8wpY*lJW0CYO${cK@8>o@R6rHLB1(lM zHvNX6U7jJtS~>CO;zCNh|lUKc{} zD4E=-53p5E*5e1&3~b%gu3z68{AQu5kWNC{3&3!zso(c#KoJ~x(s^oirUn^)qL30u zC!tT_abyMv*B`z%EF{Ow!`W@S_v2OAAh8GSkuWJPjo8KermKjH7DxfG4xF|OyD@pj z67kyk+uOsW6%W{rohA3Uu9p!sC`XmxwQqqJVfiD*>9F(~uG|49TDF$l1@4fE=k^dN zqQjqW*xRpna%E=`XA`;H8=*)b^5f#X<^Wy}Rva#GT%hBjxJ*KE386E=9vG&Dz2@=` zN#gsj#lfz$D)4A4=*X!ZT)H=WYe{tHQImXVt|;I_2@q7P#CJzZV+$OC{A<%3UVvrLoMf zv6APod%ta^(VZ4FX+s4_*0OP6x=P>b&0euP@d}s^Hx>*3Ill+l2yM^gT1`JX--nQS zgtCi!mfY|& zSs@p<_rU1~z4=Zx%>7oSEf6ew(zcaz0*wO(N4SbU3xlM{SNHlUv-1M(HqRA=iH&+p&lD6SrB_j(h8ZP83IGVOnlI~~X4NWMmKCU-TnjF@7D+liZF zKqL3ChX7He{2c|`KPV@)ROEe#hqb;dmYMrs8mb6kCq4T&XUJrWensq{0Yq+7EHD1I zHSq*nllL)WWpu3#h~L<|&7N!NU{!-a*uNZh7c!%VB_Amfii(K~13VoOJx1bkx5>t> z8=y1*EqV%406+wt89*-~*onZe5CRcavD|+D=|y0%HFR6VgiJ;z@1#%Kw6(@)q<>sC zdQf!^Rx?6_dx$uH_&eD>vw$wyuc#r`A zsl_1`sUtLpF$fGK2!Rj$M9e@BTR;{WaH)2Sc{6{E2po)nCSzuw)v1NsI6E(v3EvV{ zGa+idm7{tIjnIXc2(nXyr^($OGjuyw@o+mA=_ONh&#{Lu=HU!^no)r`Rc}7I{A{uR z(rwxyD7(TU=&jHT+g z-zx?l^yZK=FrcYDw_gX*;;Mi({o|@TGQd_OfdL^su&Yz`BA)(-OV$@m`h&AXLh=dE z$*d$(M$F}umJ8sh-NSJe)Gj&%qw=WMB2{hBoJzD!^g3J~9#%f3bq{wyMb-_iezx|x z3O>xL4`P=)+tf;=o9i>*F<#;10QM-@`)7p$!8>8!LY5|R8eDfd(YVn>X%YjncQgP} zbz~USGc4af^0w{N17V7hfX_Kwvs~X^!E~QE-%lh4RDRr;FO{8WFsKqe%mB?rNsGv^ zYc1on^JBJ4wpjvBu|@7XwnFAJJSb=sauvmH#RU@OB0SXyY5ZZS! zkVHms(1HkmXEiK6;8(8^{MklSFc_7D7fnVn!vqJu2`@wuSoK81Z$#D+12co4ZhQ&k zv9!wN0G5+@2p%7gssp7wcaPXPRC@XeismeYzj>UoZ!KkkRGE<8!Le+BqTu_zYgk=FR`-24`g68NwHSKj-!FBN<5F-HS$mEiYV1hs^ z)mK|A9nL6M(k_mmD=eMX+}c4uKnEgt<#k zB-_xvmd-M6?uit^{ss4+#|y{HHYR&*-(xFREE^c(^xM+4BuBz^FcZ}AZPo1{M=*b? z8YQU}xxDu>`j=~ob{s!keT$86{=$uL-@2)=K<7|+pA!HgDZlNuodoUC{UuBzVvc87o*0e-JNZz?L)d_^VDEdlxm#!GL?)O4H)oKjImUK0O7K|r*K zxwj0DzVuSH5{rEz7(6~CcF5S)iW&vJCzc+Ms( zi5hHgrVGKfWM!aI$zO3JJLSg8JH`P*r3@4Vi$N;sT1&0oHc*`oXN}a5reHl~HreuvCf)4nL7JE?x+VLHj3DdkDp9$!22Cd#AmrJ)AXWSb zGxp1ATB#BRF09wDH?dZX9@|>- zKfE-1yMj8Ajj&7D(8iLvuip*wU6ptj^&g&>C3G24Yv`~Y8zn=mHt^`L(#>U1q;~5G z-h6PWO{z+UR&bILC%VGp+ghm&A^=wZrLeLzPmNKAx-=Vgr*7NMW^|4c8(=99Ijut> zXd%H6TTK%rJ$PWfX{xqxgJ?a2FblhAqj=@}ULsQ}8E0+M`aj`ZL2MS3{3wNIaBJqGJhnM>u4Sws4J)cYGZw5e6 zai&k^Ybubl6jn_L2K|Tcv~us%TmD5}?cwxH?Dz~$C+IBZzLKD>0FH#z>oErN*MVFN z>KlZym?cn;{%4Z<59>t?WmVj@BQ=8piD2>^Md+af&S*dpcr?2e{JIqcmYeP#*A&UX z73GQltRTuiu)m=PU^{1rK+Auc(Hfa$E?J;uPUAjfO1*eVoo{Gm$c>Z1l^X4yy@v^P zIeX~2U>i15{J|(be#Ct@qq5d{^x1~L2yJz35C_;Wz%;lZ#MYN7;|DZ*f+?Dwx&o7u zYDjW?64Eh8{)*KwYuZ8V1O}N4?qC@!s9>{~v38K>9eUAnQw%Z!7CVI1#Bwsrc6Hd8-ua&y!@psSQzY_?sBv>OX`Cq2b8xtQK167x$ z(>vwUSg8@^^>(i9vEd`ImC!^HwG$~_BDg40GDKUU9PHkRC+HK`$ovm!POaQ;My*`( zkO{ua=hj~K{w)bX|2lct+VD(@`-`M>mTkE^X5vyNKt)AM#blu|7qo54!rC=Xje;jn zX|L%S%JM0$A++OSiUnhKG;29qet=p8IeL3%iUUPC^%s+#O;ETcjK6 z_I7@-W(=^qrc^neV=SZ4O8KYn4XsE&^o;%+!`p;DvPT5EH(j=6_RE$h@}AQmSuC0? z&G#Ok4uo>(d>xujBifrrT3{ZBwC}I?N=kO{i2a()3p==A!*4Bd6;w5wtWEoQ$N$vz zcTX^=ISv2TK|@GLP1XD@i<5IcTTJaDBWz0d8%R7L)&>2;pD15~q6LOm{II<$f$N-~ z90jZGpL&@V7mWUIMR(P^YR2>v?`@0VER~U4WOMicc6%-i& ziwH}8^F3nBI~!Pzj%>kR^X63(Bxc}Av;^LK(3kI&1P~8Mu$%#hs}HzePT!W2BbhZ1 zyrmm-DCi-P*c7*#mL|L>>n71GAk$!-Au8|m1)UCJFiuv2K4Jy#!0lHsavGDSVTdnm) z=H*%^3LZ3F!ei9obH*Mof_j5D_Ly{Vc+)ArGjp7LIZ_C3o7{pHeuGvVud4G_H)n%d zXMBHK;T(tTI?@WAIF9Y7M$ILxPivxts^g#X5oJAGAs_yem`c&cf+h#hs`FV}Y@ZhQ zi2{VnX`@jXBftT^wE(~zXw-15eMxWj?LxNJ56NGvmgmj~1~;9c)%xnc0HFb=e)getjuj-QirJQkQ-##t zU`+1=N*~T7$e_xXDqrOJSqEgq;ls0j5v}fA_r?iMRZzfH)$~g^{J_*_cQLF2lXUe-4n2`GY&A(%qj^I-qGBxcY^z5Vo zId0K@IF*L?KbcMQ3ciS+z*io4;1iDaS~ix;E;i4C(C9sx{R1!Oww>P?_qIy!o;?M) zgzCX!@R56^p6Bw##&W9h$F|@?lzT_1CJvR3I^2lU$92@W$CYdL?6c=0+|$i~+aXW6 z5NvyoK!6(_%hn<=DFncmH69Imo50T5mHgG`PA~`UC;NER^7ugs202`HkX47-3n?5l z2+mRH7+n5va1SN(@Vi*(1cxc4)l{b6^j~lP8b=liEa;4lL(>>{0bt_8C!Jn#C^)Q% zH;Ru1>!&o&+>K701z1gDp@6=5v z?8K@ZBuRGB!E<|oe{db{vnRo4>n8{8A_Z_{0g8QDZ^KY63&SHDI1 zYdpWp7a3O+x>R|7{t`dB2s}tiY5ARj-#;&p*9(S28~hz-*3!ozB~nJ1>@Pft1*Hm6 zy+~&6#;=~urJa4XaUk;d{Yd^13Y^{S{X)KJa*>_scpZD5J(g;-^-2zuwk_jGVu#?Q4yYjzAJk{$$B> zz1~Z)66pliL7Y^a9-PIvpM@{CxE$yH`vTGBq)#n7)PFsc**E{H5JD1KlxvB!;<9sf z#fpgIoPrcqfw=dtf&bSTJ00YM@75MqLwgf&Vqse!@B8U}5b@e>ui1}3n16oO-Wod= z?ocX<6w1a|3~BgBy+gXjeSclI(q?MifcjX9U)zRmY)#Uf&6n%AyQO)W4Rn9tjNkE! z5cOmJdJaZ1@yPahqGO9IwU=`Glp16^dM{!Qv(b&wJ7r?a+-%y8@lN05s_~ChYr0di z24}bn99K;#JuZP|1mJPQuYILF$aoWsn5|gKzK-@e;t6XIW&_vGS10ijWZ;TN*$!QW z=J%QkHlmr^IBTd`+ADq)G9Zu&;p0fegX0}}M!SCP<*i{~V&($;EGmEIG#EQ`s!4qh z#--e&M2!Ow-sX)l2|i8wSJrb$IJ+UEX?u-tlG%@fX+tiAy@|2n|C)AI9>C6Fs_iwW z7igG3#Ug3^lc=r?j9~hAi*GKb-%OMOjm_2G5CKtZNnu>Oby zN6wp0vYeI^;0YIFvF3MVWqU2-h1u?s=J?4U0Ufay9Gi}FYCtCO=&lK_?Teh{>!c$ewo=T@6U*#%m=F^k4|u3hD7n+#~8 znDVlPeUKRsjq06PcqBLs*j;nDi~eegy>Z94N5;ie869SS_@2Dn;l&756e)rqJLU44 z%MMJ1ex%ly+};WDc&h$3;$?~mIpVRn76>3PNNx}WEJ}YYPh`DCnP?1xOdSF~PG=W6 z7a=EO$EVYHbZEyx#l%7Dxh|{w_R`45v^y1-hHREQv>FBjl@zpptPR<+HOQW$6m4=g z+9aw|8A8ZdU5NF51bLl{%P!OJPWXD=t>jk($HK|C7U`Nzot-9Nl7PmJ*imBr}?IPr>n7pU{To*{pm`%q4{zc{Nbow+V zxZosh{^E#zm#QcDDEnCKnO`t?8;g5hWo$`nk0vtHNZY}YD;GWl;#exH|E&~ z-36#}7p)!NIs}0)1^CQzRg9#lv)h$!&WC>BD8r}XLj0S9_HKRpc)K!s=YgH?BTeH^ zlyaYFl5~jx&T<@x?q}(Vvv5kPY|E85-D!CWvvCu-*ImDAP7Z&kV4e#97SqcKO!zbt z)v79j!w%oTOsmA5*`?RWRJG>&R^^!Usp$(<(CG0K_%@ZwgXsxKTj&xl(0cd_&TI9o z>wdKwhCT#6I{dt?6gI zDXd~Iv0r!=k9?73pIP($8JEjr#~lYv_wDUAGDerngH;r@7R}K+79AY4SNJgr!xys( zA2J-C^vtzE2bxrMKVc1lEFxG9dBxkB^3X7uEeZsW;r6)tT~BRwiUVuVhz|y-$mYp_ z#u7cv(7CdCZ9a|>!0L|4$>pp`iysgA?vAsB6~BYj!YzHRCV%?7&#qXT+8tJJx9%7A zI48DK=nc1{G9blBWUR*cPnz^}yS34nUE%&_zXS>x&2*YB>+df|DCMHVX zhZ-HV#BXd8+xO4jzAWzhy0-Pi^Swz7f-4;HO`x#L*~KYDuxiL&IgK z1 zz^kMY#h_ZM5cX~@R*NJU@9wqh;6AAHYQ2Q^(TaPv=abGNwY{>b~h z`$0JPsi=yd=P6S{&O;4uZN_z!->~zYYt`^1GtoZ-;#@7bIH)5WZoo5@RZ54CJwCI! zsUVX(%|mN!D51x7Y?EM|4Y9n4Nz7X}>7d?XH1-E_a*kDG3b-BWJEpm&b=2Yzd# zJ5Dl@6~P^?C+%&41`{Jp~024%XIG!_twm#j;++v7~?o>NA8 zT4s@U{gD$grU_w!v@7VFyDCBB8dy5Fapl3D#9{`h=v6^si%xH58Nr8wo=(|af2P@Q z#__u8(WRz%`Ui~bR0QHGuV1oMs3d1}eZhzRZC0|B^ReV^b$vmM?)`fKl==eZD^pW% zZNzCqT(%3+t_u_8Xy~bFCr>K38&yb&50gid?d9Y_KAu+{WxiUQPERCV6HqEko?HA^Eq>-7f_!O5A7iqqZcS2HSnh-#jsAyUT$&=cj*)R6CAW zk(HsxGaXQFtDE&_7|GTfA|YO+-vSLbg4*BWZ^l<`#Ep4f9lD)(L#S&#u*^ZX)%vmo zhXvWOsLSk0yh6Rm*7INHv0I_;vi0N>UwQ@@{QLRrNn5Q~M9NGV4x34r*{yX_Iv(2D zp!K60PKx8Tle{$H(Z#m93$Bsp-Bp@yKV=imVpc{5p*2bieSyygji!vCIxh?bwctsM zUow;mIg_Q;c}jdo@68siTt(h!;^0f(4eJRkq3vDqhzuR99kVfNxiYG5#G_l#LEEeQ zx`)4A8+q`z!lT&NXgn&KJLbm?qa3M{j@G8#E0Z?5ivmv{CZbE=?+&jq1dk<43p9yV z4i&MUbe!)_sD>Qx@Ti;}8Gy1m9Lu>l75-rZ{(9v?v6qSMSwA^-{;+qK(UiSaO;)G5 z!$;=YA)51giyg6^MuCK1BtKqBl|S3rE&Kc@3FliI8z-ka^?54x=wA5Sm)P5DW#f$f zR#H!E1VcB~OKC7!4D!X^+>cEwPLh0@{H=lRYr%bJ);5Qx{xfv}7sg7+}laZftqnVz|fs*TUS_|&s@_$~>WnOhlMoXp=cVZ6oBCT%__VYspSd_3n}f9flw zP1O-PrNB9jXSQWL3?K5{GOhPkPfN# z$BJQg*8v*^{UT@sx+U4X+c63{QL|j@r}@Mpx{SF|JG#@@Gh6Sl3{qCo9b|Th}>9v!84nBobyJ@;_&;<<-MEJTs$M4hN$}hH~ z%v;Cbm$0-g2OOL{)M%)6l<60|v3ABCH}Ue_BZ^Pmzhm+(hx{klhd#8lNnbV;&b)!P z*jt}}Kbg4Y_p_Aw&n#wBU`&Z?d9>U+=$#FbPQed#&mfcTs|P4A2I2q-|2FT1-#WZn z(M+YFz{jZCwnZ~vQ%Pi+7azCV*Q5-^h)n0)zhfCE@ZnFCP55|tRTQKldft?&Cq6wt zkojan)Pk!iV2&Ku#=qIIwThGoKHd@C-(xu7nG90e@MGF-IXM1~#L@(j@DT5E!62BYJ&4 z_{Ps3=|=#P-FthfsC7c|S)mEN?6&-ii{(LveKdQUit3|Q(N|r1=JV)A$)3w8e>B&u zYxsVmbS3tgl}%pcxvh;Bk$NZpZSAencArVQ`Ya8zxnkUkJca5e$BFY z{i~)ar|NBh*;!k_tX9(KONK|0EKh8nxIQnul|ts&H^w|FU6U(jXxXk6*r#2YQ{rp1 zP5n#Mvc&dzUWH6g`!kfXhQ@gOB$nOcuEDcE@y@5C$;c%BE!CXQjS=TAIVuNu-`?Ym zlm}VXlg~bz4LJ);B}MnMeRm)#dX5TM?-R9Dg?|3KL=!MmF!JC{{4+1AzZ+HaZN^Xg zUmm-qMX}W&GuHZ{S*B2AND|)^u#vg7#CIFNq6kxu|(!N zI=f+`sw*K{OqFPUAwC1SdAG1oR;JQ9ds>|DWANiFjmjMGJn7taD z&Yi=*zCtY5>F^kdbex2{D(QV(j`CSV?Sl`2MCcOIjO_X;k z*;=3&w+Az|cv0S`xzSpxpm6(pT9VJkb`6xm zHg4k%_V!<>J3@=|BUf6(BVvvOxljRtf%Qg7PZvMf>ex!eC$J{vTs06c%yEu^S3g&V zn)@&P+%`^mT*?q|kE$rH>*{EIl+g*R^7yB+S^KI#!8W6s1`_oz63lu~E=CjtOpwHGZ^mtFsJ`oukO|S26vlsFYJQg%Z;- z&$&7J@W_1w$FiL@ z$n=lu7JO_;)2w6u2(gsCXBqb;LjvEzK<2!JaesW+YPvmk6G~rr-S6QLXTaaQipu8i zpSf8~Hs60C*KKOxelC{ZuYbL9%Yw5+nyR{GPWhvgx3)KAOtiBrJeh`yD85;oSZFwZCopEpikqD=I98?rbJ8)_Qu*Bd2+6Zthc$BBb8!fQ)x*fSio+|BL8 zN57dFp^bdtSEL|kJq*^L4&_IQ+s$pu^b3z}Vx%8R2)tn%Co*a)u%R~D(0nKu5?ytn zcyh$Gi&R`uJ>Ojx%!iJ!XkWf6z`ym^yiUT2X)XRqA>tk`-i}#?qmTXL9zNtCAbx*S zY4^@?zaI|#A!=+<0FBXVPr2h3Q;4)@JA+LL@tLI*eve$n^Q<+tWm?eYQ^!vp#k)E8 z>9HS2sLM~h&5yXJ+MbW!+Cu%FkKr2;_gd=>|GT(d{1Y0)fU4IHEug5&Qw;RB#if<} zb){YVggUMZDU@q`c(Gf2{v_Z-+UwI@G-mB%?(}oXi>~B=ER|OZgT(m3Nm)%Eq5a?C z^J}98(Mac`2Uin!q|ev3Z9YKjxAJwr7S+vr9lS_N7otZ)N{jhj!qZY1RiuTIuP#XJ zz0UZ#3K{w#D(IRQ5^a$HNzDqp9estzB&prl>O0@sTamI)f6sS~Vf5-wd7MPCwT;o- zaS6{B_{IfOn*7Xbofi$e8D3Csl+HucJ57^?UHaJe%$E5op4MN1IEvjNdINR*Df;FU zITOFJ#!#(8%UT_gQ(*7TmttLMD}E6zBzAu`6B6`8jbe+b|V(Hjm_Dj>y==DjO{ z$JRGIs;mT zug5=HFc}>v$3n|5=YD)!AFqcSvKD*2((OC7aF~|N7~gnNO~}X>x5{5sn{SHSkn{K0 z<@LOH#+h9~N%qNcUn`+}SY`8bYtPM4Z#4ByzF@2T+VpOhwV6C^$k6V54Fmce_k~o< zUiVP%-?I6|QAIt;g?du|Uh*DRI@|FLH(JZCYdqRBdTfP7jZVzo z?^O|pk_Xx5WK$*f#CJ-5PeeOvd+Rdndn`U;eHf z^|9Hi{pq9+g9T+E*3BczK|D^qytXVv)gtcB&dWVklOOK}W+dNnR^f!VlV0>I_uLBn zP)t72qu}*L^g;1kV&P=}QXfw9U|+rdRA{I~v^`GQMUpCT;c%~a((=yYM%FMYn9ZE^ z3xeazxrQUJ@EBtI8Vp7)~(-V?VvH}xkbzgqU5odqsruwSzwn;#7fYpd(~#c8xT z7*K00;;+4A!RVq`l5BB&ZQen1a~rAKrRi$awWPf)^=kZa8~GzmxY6EtZ*$yX8^iff zZ|LU=lZ2(V^S{zxYM4%xe&*?I9~oPkxGJUgA8#_i-*V>L>f9+H-ZlB*`OCA9T`Q&O zPJHaE(7xBen8TaYZ)OU^I;)P_fU3(-aHIvV~idt1!g z0;lijOd8*05sSO4*2}f#_Nnz;k|%-xb+6-G=PzT*jStti-0;0B8KYk^v{@#Xg$aO} z^3C}3ccgk<>x;~j;r%F+*aX=^o+FI<_!#$&UCL?YJiclF9cHZN>fuHlB9Q|t^|ODi#j!BnGQ{2a~iEic`zINiDW2S^QU8DI#ZRhY%a$y7grbsqQq15Mtuz(V&T0Uu-r{}c|U(pTE zO-Xt2&WYASREI7slBQ?&Fp!|AM~}r-jhg}qpDN7n2W^CaX%=DV3B4_C_H?;BcG}=t zewh%PzayL+REbLDH{*jR5<>m80=ze?)nZd?&3Q->}@Pw{yz7Q3KDol6b(2E9$Ay=H_zUN)Pj0*sckZ zw%`@|C`ef=zr9CAH4O)#n4>5=Y4=q%61B_X{Z?I3o?mLcC4USU* z4%TH87T2#d+U8QyGZ)TYZ7pFJ^rpO&H-X6i+>5o}kXXr&LSuKS4lzX8DCkd7Hb10E znN67kc*FUubWIuq%6(YxT4K+z*FJh)EONn1{Vs(}g@sRw6@8%$4K`Esy{f7jCiHU` zKFRSB37$5T{z^Jwr<7>6%sA&sH&ZY=UB`~F=X2R0et zM#g=Km4(jdquZGd_wuri6ZoUnSii)$uqy$e!~&fkyqHN~Lt99ZC@>@%Gk zs8>}J(eqYk%S@~aS=J^p6hzM6em)J@usj{Kl*H|HB&mabqWv$jbYtz`NLMB4nI&vy zBvGt`;Jn~xB1NUb@5={#ViPwM;#+0#uV^OeB|y#WCD$Y{yj0`3BFkm9C!=l{e~$Yx z#yKi_D&*`#r3X(~MN8w`Hu{S$wzLWehp>T^#&?72Q|CAPoVK0GglE%p)b(x4qH-Mf zC+lJRe;eYR_Y!l&W|!SbH&o#zhP7Jd?Q`TQjyE3n1?;|*SlCC(jSVGd&(2Cz zwmQ;c!RwM&1Rg{%O&pksZ${C^HPiFr=lswXY+(F)ryg`R7aoI(dR;X4wDeC|nu20B z9J&1xk=Q@yza|kU@Lm9=<++lp^P$HQis8>yDi*m+5{_AMjS&X{DQq(R45I>@Yn{Mq zG&WO8LoV9iEZZxorNWV@WiZc1ut!rWI`HR!aWr9NllN?N*|Xt~lQf}qMrK=N>=5O6 z)-dKkCp)?ABQ}!G3X5@zOZQQ=uLef*U8yrW$W}Uz8i;L#mpq?^Qp!Y@zBy)DI{f zy9UTqM9XbsugrTd2kYww`u7~gVbp*5QA_p=s zcnSNKp6pziIv%(+>hMd@71A^5$Y3-f`@csbpXkdW>#75IR!+<4b4&pbAB1Yyst|uq zncTBRuqaCLE1?i;s)q29E~8o}u*iYiyOZ43(l3@IE$ga=%CF{TejK+!bn&+9g7smM z>*)YG^j7;tHe#n!m5FDU=*@v2AJc3tgR=W;B^S?;qK$VFhYYr1R=W97jnG?Vzb(Ly zvlOSDph1Aj9ZgWh`4+HN9wPLKzPL`}b;8}gb2+(f$AavGC_%-AZX_S8W%J*1m=6l^ z5Ag*u2FLM}by`XxOU?+YYS|1F>{*xXVkSE~M)SZI1z_eVH+k==R_AFbx{xL!?Rk#U z%Xwc(W{2fJ&#eYb#7GxW>C_v|x3ntAM(Rm8#s?&-8;BRcpCvoTUL}6eH)ef17QF zBKHdb_$|Vj{^1npdyyK>m#jRxt7YsBcdd(;?c{rKFs0OZtyxwh^1p*gFMOdf%QcW= z46Rr<4Mxf`7OK0*Kf`*;G z?%IvLRM0KmtXSN@m$(M5H=23NJyb+c_yyx-Nz@Isq+4KcstudC!VAyf}CK0t7=_01q36Usdw_*5RC@+O3 z&%A21)xd{Y&R%6sZ0nSd)=*pY`mE@s?M)8~C1jF${-psmQNEE8hkKi{I)61JBfpv4R?IRz8h>GN{XR)KmvMfKnyRpU7J>R1CVtmm~gny7p zD|6KNbk z;->^9({3Y*PQ9b9-zO>in^!WI70Qu{6Mv@+4T3={i{}o?FS||G#&y3-v{m_vv5(aB ziQFxmT1a4gP`mL=CR+r9W-Oe^hP1j|&zDW}^D-P1wf*r#op!Uy zFT!f&>&C$akIQTgfsVKTB47Ejd%Z|hF)-b9>vLB5Wq*Eta+d(c7wk2u!C!x!oVH5r zfNqanA1qjnuW#WR=U7Y`(Do<_YhZ7|jJ^;@`Z|IsWm%0DrmE?k@l*TNKg-zMB!69B zef`JmKZTJwEbV1Q>6wwrF7ePG_@|%K+x$zXx-2Gt$}m3gIswUNZA8>mmN#6h9Q>Kl zRE4vw*UScJ)nq68w*j~yas_b!8rL5HDc{%= zRwcbsUb7LgaVx4BJr^xMWuu~IY0wXi;2Ho^7d-&RMt1rwi<9-AOT z-ns1C)snXsyKl}a%k-IjuN2M{LYL{-f|&l8h7V6RY~R2uyoJGVYjo7jktgKbK?$WcJOYIW|xD(lX+50$!BV%7{5Pg z6>ha(-g@=WpF-bd50=fmiXL?+uZsTtprB4zzfrz(AbCmg>x$sga(O;y*9Gc2Bq_mi4+1NUEoHyT4kM5KlhmI?}~hPq5bnSxNZ3v-rp+4!b64 zco$;U6>eIJrvZ8*&6X6nFY0EEQ0W70^2qjjlb=UM;$=P^o?H-%%h&4G)D8Y&0{hMw zLzWBAS5WuM-s!x!ncA}>to~5V$pN-HK>ioDx1S#xB(XPWhx3{)-JCoU!Gy%G;<+YE z#>c5bj~uoc+_`-Uf*&damoIK|MoCiIqen7(2Vw8TDn|@^C*Zg&vFpt5@Za}w%;%oF zw}d-gI{c1?Hz>k?l0Tff&9AI4T)^tLhcy1jp+4c~btgH`_Wz)#OwRw

t+FH5H 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/wrapper-back.png b/spec/test_app/public/images/wrapper-back.png new file mode 100644 index 0000000000000000000000000000000000000000..60066367ced325835523e3c5dae504dfaa353e63 GIT binary patch literal 41748 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%0Ae)`MwzV0&EhpUnL89jRQ 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/yui-menubaritem_submenuindicator.png b/spec/test_app/public/images/yui-menubaritem_submenuindicator.png new file mode 100644 index 0000000000000000000000000000000000000000..030941c9cffc064276813d7eaab03d8c667ed700 GIT binary patch literal 3618 zcmV+-4&CvIP)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=00004XF*Lt006O$eEU(80000WV@Og>004R=004l4008;_004mL004C` z008P>0026e000+nl3&F}00093P)t-s00030|NjC40s{jB1Ox;H1qB8M1_uWR2nYxX z2?+`c3JVJh3=9kn4Gj(s4i66x5D*X%5fKs+5)%^>6ciK{6%`g178e&67#J8C85tTH z8XFrM92^`S9UUGX9v>ecARr(iAt53nA|oRsBqSsyB_$>%CMPE+C@3f?DJd!{Dl021 zEG#T7EiEoCE-x=HFfcGNF)=bSGBYzXG&D3dH8nOiHa9mnI5;>tIXOByIy*Z%JUl!- zJv}}?K0iM{KtMo2K|w-7LPJACL_|bIMMXwNMn^|SNJvOYNl8jdN=r*iOiWBoO-)Wt zPESuyP*6}&QBhJ-Qd3h?R8&+|RaI72R##V7SXfwDSy@_IT3cINTwGjTU0q&YUSD5d zU|?WjVPRroVq;@tWMpJzWo2e&W@l$-XlQ6@X=!R|YHMq2Y;0_8ZEbFDZf|dIaBy&O zadC2Ta&vQYbaZreb#-=jc6WDoczAeud3kzzdV70&e0+R;eSLm@et&;|fPjF3fq{a8 zf`fyDgoK2Jg@uNOhKGlTh=_=ZiHVAeii?YjjEszpjg5|uj*pLzkdTm(k&%*;l9Q8@ zl$4Z}m6ev3mY0{8n3$NEnVFiJnwy)OoSdAUot>VZo}ZteprD|kp`oIpqNAguq@<*! zrKP5(rl+T;sHmu^si~@}s;jH3tgNi9t*x%EuCK4Ju&}VPv9YqUva_?Zw6wIfwY9dk zwzs#pxVX5vxw*Q!y1To(yu7@dCU z$jHda$;ryf%FD~k%*@Qq&CSlv&d<-!(9qD)(b3Y<($mw^)YR0~)z#M4*4Nk9*x1lt)=I7_<=;-L_>FMg~ z>g((4?Ck9A?d|UF?(gsK@bK{Q@$vHV^7Hfa^z`)g_4W4l_V@Sq`1ttw`T6?#`uqF) z{QUg={r&#_{{R2~`6RjA00002bW%=J{{ZE;FiHRb03%66K~#9!Vqky(Mi^jVMCCIw oFfyX>85y7$4gdfE0RR6300puDFk literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/yui-menubaritem_submenuindicator_disabled.png b/spec/test_app/public/images/yui-menubaritem_submenuindicator_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..6c1612230550ef09678a38a2e3374585055a07eb GIT binary patch literal 3618 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/yui-menuitem_submenuindicator_disabled.png b/spec/test_app/public/images/yui-menuitem_submenuindicator_disabled.png new file mode 100644 index 0000000000000000000000000000000000000000..427d60a38af14ac7b530a266dc2e969555d287c7 GIT binary patch literal 3617 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/images/yui-sprite.png b/spec/test_app/public/images/yui-sprite.png new file mode 100644 index 0000000000000000000000000000000000000000..afd65e05aaabc820fc2e6bba0740818773fcd599 GIT binary patch literal 3123 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/additional-methods.js b/spec/test_app/public/javascripts/additional-methods.js new file mode 100644 index 0000000..49abf4c --- /dev/null +++ b/spec/test_app/public/javascripts/additional-methods.js @@ -0,0 +1,236 @@ +jQuery.validator.addMethod("maxWords", function(value, element, params) { + return this.optional(element) || value.match(/\b\w+\b/g).length < params; +}, jQuery.validator.format("Please enter {0} words or less.")); + +jQuery.validator.addMethod("minWords", function(value, element, params) { + return this.optional(element) || value.match(/\b\w+\b/g).length >= params; +}, jQuery.validator.format("Please enter at least {0} words.")); + +jQuery.validator.addMethod("rangeWords", function(value, element, params) { + return this.optional(element) || value.match(/\b\w+\b/g).length >= params[0] && value.match(/bw+b/g).length < params[1]; +}, jQuery.validator.format("Please enter between {0} and {1} words.")); + + +jQuery.validator.addMethod("letterswithbasicpunc", function(value, element) { + return this.optional(element) || /^[a-z-.,()'\"\s]+$/i.test(value); +}, "Letters or punctuation only please"); + +jQuery.validator.addMethod("alphanumeric", function(value, element) { + return this.optional(element) || /^\w+$/i.test(value); +}, "Letters, numbers, spaces or underscores only please"); + +jQuery.validator.addMethod("lettersonly", function(value, element) { + return this.optional(element) || /^[a-z]+$/i.test(value); +}, "Letters only please"); + +jQuery.validator.addMethod("nowhitespace", function(value, element) { + return this.optional(element) || /^\S+$/i.test(value); +}, "No white space please"); + +jQuery.validator.addMethod("ziprange", function(value, element) { + return this.optional(element) || /^90[2-5]\d\{2}-\d{4}$/.test(value); +}, "Your ZIP-code must be in the range 902xx-xxxx to 905-xx-xxxx"); + +/** +* Return true, if the value is a valid vehicle identification number (VIN). +* +* Works with all kind of text inputs. +* +* @example +* @desc Declares a required input element whose value must be a valid vehicle identification number. +* +* @name jQuery.validator.methods.vinUS +* @type Boolean +* @cat Plugins/Validate/Methods +*/ +jQuery.validator.addMethod( + "vinUS", + function(v){ + if (v.length != 17) + return false; + var i, n, d, f, cd, cdv; + var LL = ["A","B","C","D","E","F","G","H","J","K","L","M","N","P","R","S","T","U","V","W","X","Y","Z"]; + var VL = [1,2,3,4,5,6,7,8,1,2,3,4,5,7,9,2,3,4,5,6,7,8,9]; + var FL = [8,7,6,5,4,3,2,10,0,9,8,7,6,5,4,3,2]; + var rs = 0; + for(i = 0; i < 17; i++){ + f = FL[i]; + d = v.slice(i,i+1); + if(i == 8){ + cdv = d; + } + if(!isNaN(d)){ + d *= f; + } + else{ + for(n = 0; n < LL.length; n++){ + if(d.toUpperCase() === LL[n]){ + d = VL[n]; + d *= f; + if(isNaN(cdv) && n == 8){ + cdv = LL[n]; + } + break; + } + } + } + rs += d; + } + cd = rs % 11; + if(cd == 10){cd = "X";} + if(cd == cdv){return true;} + return false; + }, + "The specified vehicle identification number (VIN) is invalid." +); + +/** + * Return true, if the value is a valid date, also making this formal check dd/mm/yyyy. + * + * @example jQuery.validator.methods.date("01/01/1900") + * @result true + * + * @example jQuery.validator.methods.date("01/13/1990") + * @result false + * + * @example jQuery.validator.methods.date("01.01.1900") + * @result false + * + * @example + * @desc Declares an optional input element whose value must be a valid date. + * + * @name jQuery.validator.methods.dateITA + * @type Boolean + * @cat Plugins/Validate/Methods + */ +jQuery.validator.addMethod( + "dateITA", + function(value, element) { + var check = false; + var re = /^\d{1,2}\/\d{1,2}\/\d{4}$/ + if( re.test(value)){ + var adata = value.split('/'); + var gg = parseInt(adata[0],10); + var mm = parseInt(adata[1],10); + var aaaa = parseInt(adata[2],10); + var xdata = new Date(aaaa,mm-1,gg); + if ( ( xdata.getFullYear() == aaaa ) && ( xdata.getMonth () == mm - 1 ) && ( xdata.getDate() == gg ) ) + check = true; + else + check = false; + } else + check = false; + return this.optional(element) || check; + }, + "Please enter a correct date" +); + +jQuery.validator.addMethod("dateNL", function(value, element) { + return this.optional(element) || /^\d\d?[\.\/-]\d\d?[\.\/-]\d\d\d?\d?$/.test(value); + }, "Vul hier een geldige datum in." +); + +jQuery.validator.addMethod("time", function(value, element) { + return this.optional(element) || /^([01][0-9])|(2[0123]):([0-5])([0-9])$/.test(value); + }, "Please enter a valid time, between 00:00 and 23:59" +); + +/** + * matches US phone number format + * + * where the area code may not start with 1 and the prefix may not start with 1 + * allows '-' or ' ' as a separator and allows parens around area code + * some people may want to put a '1' in front of their number + * + * 1(212)-999-2345 + * or + * 212 999 2344 + * or + * 212-999-0983 + * + * but not + * 111-123-5434 + * and not + * 212 123 4567 + */ +jQuery.validator.addMethod("phone", function(phone_number, element) { + phone_number = phone_number.replace(/\s+/g, ""); + return this.optional(element) || phone_number.length > 9 && + phone_number.match(/^(1-?)?(\([2-9]\d{2}\)|[2-9]\d{2})-?[2-9]\d{2}-?\d{4}$/); +}, "Please specify a valid phone number"); + +// TODO check if value starts with <, otherwise don't try stripping anything +jQuery.validator.addMethod("strippedminlength", function(value, element, param) { + return jQuery(value).text().length >= param; +}, jQuery.validator.format("Please enter at least {0} characters")); + +// same as email, but TLD is optional +jQuery.validator.addMethod("email2", function(value, element, param) { + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); +}, jQuery.validator.messages.email); + +// same as url, but TLD is optional +jQuery.validator.addMethod("url2", function(value, element, param) { + return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)*(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); +}, jQuery.validator.messages.url); + +// NOTICE: Modified version of Castle.Components.Validator.CreditCardValidator +// Redistributed under the the Apache License 2.0 at http://www.apache.org/licenses/LICENSE-2.0 +// Valid Types: mastercard, visa, amex, dinersclub, enroute, discover, jcb, unknown, all (overrides all other settings) +jQuery.validator.addMethod("creditcardtypes", function(value, element, param) { + + if (/[^0-9-]+/.test(value)) + return false; + + value = value.replace(/\D/g, ""); + + var validTypes = 0x0000; + + if (param.mastercard) + validTypes |= 0x0001; + if (param.visa) + validTypes |= 0x0002; + if (param.amex) + validTypes |= 0x0004; + if (param.dinersclub) + validTypes |= 0x0008; + if (param.enroute) + validTypes |= 0x0010; + if (param.discover) + validTypes |= 0x0020; + if (param.jcb) + validTypes |= 0x0040; + if (param.unknown) + validTypes |= 0x0080; + if (param.all) + validTypes = 0x0001 | 0x0002 | 0x0004 | 0x0008 | 0x0010 | 0x0020 | 0x0040 | 0x0080; + + if (validTypes & 0x0001 && /^(51|52|53|54|55)/.test(value)) { //mastercard + return value.length == 16; + } + if (validTypes & 0x0002 && /^(4)/.test(value)) { //visa + return value.length == 16; + } + if (validTypes & 0x0004 && /^(34|37)/.test(value)) { //amex + return value.length == 15; + } + if (validTypes & 0x0008 && /^(300|301|302|303|304|305|36|38)/.test(value)) { //dinersclub + return value.length == 14; + } + if (validTypes & 0x0010 && /^(2014|2149)/.test(value)) { //enroute + return value.length == 15; + } + if (validTypes & 0x0020 && /^(6011)/.test(value)) { //discover + return value.length == 16; + } + if (validTypes & 0x0040 && /^(3)/.test(value)) { //jcb + return value.length == 16; + } + if (validTypes & 0x0040 && /^(2131|1800)/.test(value)) { //jcb + return value.length == 15; + } + if (validTypes & 0x0080) { //unknown + return true; + } + return false; +}, "Please enter a valid credit card number."); diff --git a/spec/test_app/public/javascripts/admin.js b/spec/test_app/public/javascripts/admin.js new file mode 100644 index 0000000..761ca61 --- /dev/null +++ b/spec/test_app/public/javascripts/admin.js @@ -0,0 +1,226 @@ +/** +This is a collection of javascript functions and whatnot +under the spree namespace that do stuff we find helpful. +Hopefully, this will evolve into a propper class. +**/ + +var spree; +if (!spree) spree = {}; + +jQuery.noConflict() ; + +jQuery(document).ajaxStart(function(){ + jQuery("#progress").slideDown(); +}); + +jQuery(document).ajaxStop(function(){ + jQuery("#progress").slideUp(); +}); + +jQuery.fn.visible = function(cond) { this[cond ? 'show' : 'hide' ]() }; + +// Apply to individual radio button that makes another element visible when checked +jQuery.fn.radioControlsVisibilityOfElement = function(dependentElementSelector){ + if(!this.get(0)){ return } + showValue = this.get(0).value; + radioGroup = $("input[name='" + this.get(0).name + "']"); + radioGroup.each(function(){ + jQuery(this).click(function(){ + jQuery(dependentElementSelector).visible(this.checked && this.value == showValue) + }); + if(this.checked){ this.click() } + }); +} + +var request = function(options) { + jQuery.ajax(jQuery.extend({ dataType: 'script', url: options.url, type: 'get' }, options)); + return false; +}; + +// remote links handler +jQuery('a[data-remote=true]').live('click', function() { + if(confirm_msg = jQuery(this).attr("data-confirm")){ + if (!confirm(confirm_msg)) return false; + } + if(method = jQuery(this).attr("data-method")){ + return request({ url: this.href, type: 'POST', data: {'_method': method} }); + } else { + update_target = jQuery(this).attr("data-update"); + link_container = jQuery(this).parent(); + if (update_target) { + if ($("#"+update_target).length == 0) { + if ($("#"+update_target.replace('_', '-')).length > 0) { + update_target = update_target.replace('_', '-') + } else { + alert("

not found, add it to view to allow AJAX request."); + return true; + } + } + } + jQuery.ajax({ dataType: 'script', url: this.href, type: 'get', + success: function(data){ + if (update_target) { + $("#"+update_target).html(data); + link_container.hide(); + } + } + }); + return false; + } +}); + +// remote forms handler +jQuery('form[data-remote=true]').live('submit', function() { + return request({ url : this.action, type : this.method, data : jQuery(this).serialize() }); +}); + + + + +// Product autocompletion +image_html = function(item){ + return ""; +} + +format_autocomplete = function(data){ + var html = ""; + + var product = data['product']; + + if(data['variant']==undefined){ + // product + + if(product['images'].length!=0){ + html = image_html(product); + } + + html += "

" + product['name'] + "

"; + html += "Sku: " + product['master']['sku'] + ""; + html += "On Hand: " + product['count_on_hand'] + "
"; + }else{ + // variant + var variant = data['variant']; + var name = product['name']; + + if(variant['images'].length!=0){ + html = image_html(variant); + }else{ + if(product['images'].length!=0){ + html = image_html(product); + } + } + + name += " - " + $.map(variant['option_values'], function(option_value){ + return option_value["option_type"]["presentation"] + ": " + option_value['name']; + }).join(", ") + + html += "

" + name + "

"; + html += "Sku: " + variant['sku'] + ""; + html += "On Hand: " + variant['count_on_hand'] + "
"; + } + + + return html +} + + +prep_autocomplete_data = function(data){ + return $.map(eval(data), function(row) { + + var product = row['product']; + + if(product['variants'].length>0 && expand_variants){ + //variants + return $.map(product['variants'], function(variant){ + + var name = product['name']; + name += " - " + $.map(variant['option_values'], function(option_value){ + return option_value["option_type"]["presentation"] + ": " + option_value['name']; + }).join(", "); + + return { + data: {product: product, variant: variant}, + value: name, + result: name + } + }); + }else{ + return { + data: {product: product}, + value: product['name'], + result: product['name'] + } + } + }); +} + +jQuery.fn.product_autocomplete = function(){ + $(this).autocomplete("/admin/products.json?authenticity_token=" + $('meta[name=csrf-token]').attr("content"), { + parse: prep_autocomplete_data, + formatItem: function(item) { + return format_autocomplete(item); + } + }).result(function(event, data, formatted) { + if (data){ + if(data['variant']==undefined){ + // product + $('#add_variant_id').val(data['product']['master']['id']); + }else{ + // variant + $('#add_variant_id').val(data['variant']['id']); + } + } + }); +} + + + +jQuery.fn.objectPicker = function(url){ + jQuery(this).tokenInput(url + "&authenticity_token=" + AUTH_TOKEN, { + searchDelay : 600, + hintText : strings.type_to_search, + noResultsText : strings.no_results, + searchingText : strings.searching, + prePopulateFromInput : true + }); +}; + +jQuery.fn.productPicker = function(){ + jQuery(this).objectPicker(ajax_urls.product_search_basic_json); +} +jQuery.fn.userPicker = function(){ + jQuery(this).objectPicker(ajax_urls.user_search_basic_json); +} + +jQuery(document).ready(function() { + + jQuery('.tokeninput.products').productPicker(); + jQuery('.tokeninput.users').userPicker(); + +}); + +function add_fields(target, association, content) { + var new_id = new Date().getTime(); + var regexp = new RegExp("new_" + association, "g"); + $(target).append(content.replace(regexp, new_id)); +} + +jQuery('a.remove_fields').live('click', function() { + $(this).prev("input[type=hidden]").val("1"); + $(this).closest(".fields").hide(); + return false; +}); + +jQuery(".observe_field").live('change', function() { + target = $(this).attr("data-update"); + ajax_indicator = $(this).attr("data-ajax-indicator") || '#busy_indicator'; + $(target).hide(); + $(ajax_indicator).show(); + $.get($(this).attr("data-base-url")+encodeURIComponent($(this).val()), + function(data) { + $(target).html(data); + $(ajax_indicator).hide(); + $(target).show(); + } + ); +}); diff --git a/spec/test_app/public/javascripts/admin/address_states.js b/spec/test_app/public/javascripts/admin/address_states.js new file mode 100644 index 0000000..56ddff6 --- /dev/null +++ b/spec/test_app/public/javascripts/admin/address_states.js @@ -0,0 +1,25 @@ +var update_state = function(region) { + var country = $('span#' + region + 'country :only-child').val(); + var states = state_mapper[country]; + + var state_select = $('span#' + region + 'state select'); + var state_input = $('span#' + region + 'state input'); + + if(states) { + state_select.html(''); + var states_with_blank = [["",""]].concat(states); + $.each(states_with_blank, function(pos,id_nm) { + var opt = $(document.createElement('option')) + .attr('value', id_nm[0]) + .html(id_nm[1]); + state_select.append(opt); + }); + state_select.enable().show();; + state_input.hide().disable(); + + } else { + state_input.enable().show(); + state_select.hide().disable(); + } + +}; \ No newline at end of file diff --git a/spec/test_app/public/javascripts/admin/checkouts/edit.js b/spec/test_app/public/javascripts/admin/checkouts/edit.js new file mode 100644 index 0000000..25cbc38 --- /dev/null +++ b/spec/test_app/public/javascripts/admin/checkouts/edit.js @@ -0,0 +1,129 @@ +jQuery(document).ready(function(){ + add_address = function(addr){ + var html = ""; + if(addr!=undefined){ + html += addr['firstname'] + " " + addr['lastname'] + ", "; + html += addr['address1'] + ", " + addr['address2'] + ", "; + html += addr['city'] + ", "; + + if(addr['state_id']!=null){ + html += addr['state']['name'] + ", "; + }else{ + html += addr['state_name'] + ", "; + } + + html += addr['country']['name']; + } + return html; + } + + format_autocomplete = function(data){ + var html = "

" + data['email'] +"

"; + html += "Billing: "; + html += add_address(data['bill_address']); + html += ""; + + html += "Shipping: "; + html += add_address(data['ship_address']); + html += ""; + + return html + } + + prep_autocomplete_data = function(data){ + return $.map(eval(data), function(row) { + return { + data: row['user'], + value: row['user']['email'], + result: row['user']['email'] + } + }); + } + + $("#customer_search").autocomplete("/admin/users.json?authenticity_token=" + $('meta[name=csrf-token]').attr("content"), { + minChars: 5, + delay: 1500, + parse: prep_autocomplete_data, + formatItem: function(item) { + return format_autocomplete(item); + } + }).result(function(event, data, formatted) { + $('#user_id').val(data['id']); + $('#guest_checkout_true').removeAttr("checked"); + $('#guest_checkout_false').attr("checked", "checked"); + $('#guest_checkout_false').removeAttr("disabled"); + $('#checkout_email').val(data['email']); + + var addr = data['bill_address']; + if(addr!=undefined){ + $('#checkout_bill_address_attributes_firstname').val(addr['firstname']); + $('#checkout_bill_address_attributes_lastname').val(addr['lastname']); + $('#checkout_bill_address_attributes_address1').val(addr['address1']); + $('#checkout_bill_address_attributes_address2').val(addr['address2']); + $('#checkout_bill_address_attributes_city').val(addr['city']); + $('#checkout_bill_address_attributes_zipcode').val(addr['zipcode']); + $('#checkout_bill_address_attributes_state_id').val(addr['state_id']); + $('#checkout_bill_address_attributes_country_id').val(addr['country_id']); + $('#checkout_bill_address_attributes_phone').val(addr['phone']); + } + + var addr = data['ship_address']; + if(addr!=undefined){ + $('#checkout_ship_address_attributes_firstname').val(addr['firstname']); + $('#checkout_ship_address_attributes_lastname').val(addr['lastname']); + $('#checkout_ship_address_attributes_address1').val(addr['address1']); + $('#checkout_ship_address_attributes_address2').val(addr['address2']); + $('#checkout_ship_address_attributes_city').val(addr['city']); + $('#checkout_ship_address_attributes_zipcode').val(addr['zipcode']); + $('#checkout_ship_address_attributes_state_id').val(addr['state_id']); + $('#checkout_ship_address_attributes_country_id').val(addr['country_id']); + $('#checkout_ship_address_attributes_phone').val(addr['phone']); + } + }); + + + $('input#checkout_use_billing').click(function() { + show_billing(!this.checked); + }); + + $('#guest_checkout_true').change(function() { + $('#customer_search').val(""); + $('#user_id').val(""); + $('#checkout_email').val(""); + $('#guest_checkout_false').attr("disabled", "true"); + + $('#checkout_bill_address_attributes_firstname').val(""); + $('#checkout_bill_address_attributes_lastname').val(""); + $('#checkout_bill_address_attributes_address1').val(""); + $('#checkout_bill_address_attributes_address2').val(""); + $('#checkout_bill_address_attributes_city').val(""); + $('#checkout_bill_address_attributes_zipcode').val(""); + $('#checkout_bill_address_attributes_state_id').val(""); + $('#checkout_bill_address_attributes_country_id').val(""); + $('#checkout_bill_address_attributes_phone').val(""); + + $('#checkout_ship_address_attributes_firstname').val(""); + $('#checkout_ship_address_attributes_lastname').val(""); + $('#checkout_ship_address_attributes_address1').val(""); + $('#checkout_ship_address_attributes_address2').val(""); + $('#checkout_ship_address_attributes_city').val(""); + $('#checkout_ship_address_attributes_zipcode').val(""); + $('#checkout_ship_address_attributes_state_id').val(""); + $('#checkout_ship_address_attributes_country_id').val(""); + $('#checkout_ship_address_attributes_phone').val(""); + }); + + var show_billing = function(show) { + if(show) { + $('#shipping').show(); + $('#shipping input').removeAttr('disabled', 'disabled'); + $('#shipping select').removeAttr('disabled', 'disabled'); + } else { + $('#shipping').hide(); + $('#shipping input').attr('disabled', 'disabled'); + $('#shipping select').attr('disabled', 'disabled'); + } + } + +}); + diff --git a/spec/test_app/public/javascripts/admin/orders/edit.js b/spec/test_app/public/javascripts/admin/orders/edit.js new file mode 100644 index 0000000..90f5508 --- /dev/null +++ b/spec/test_app/public/javascripts/admin/orders/edit.js @@ -0,0 +1,23 @@ +jQuery(document).ready(function(){ + + $("#add_product_name").product_autocomplete(); + + $("#add_line_item_to_order").live("click", function(){ + if($('#add_variant_id').val() == ''){ return false; } + update_target = jQuery(this).attr("data-update"); + jQuery.ajax({ dataType: 'script', url: this.href, type: "POST", + data: {"line_item[variant_id]": $('#add_variant_id').val(), + "line_item[quantity]": $('#add_quantity').val()}, + success: function(data){ + $("#"+update_target).html(data); + $('#add_product_name').val(''); + $('#add_variant_id').val(''); + $('#add_quantity').val(1) + } + }); + return false; + }); + +}); + + diff --git a/spec/test_app/public/javascripts/admin/orders/edit_form.js b/spec/test_app/public/javascripts/admin/orders/edit_form.js new file mode 100644 index 0000000..114de45 --- /dev/null +++ b/spec/test_app/public/javascripts/admin/orders/edit_form.js @@ -0,0 +1,15 @@ + $.each($('td.qty input'), function(i, inpt){ + $(inpt).delayedObserver(0.5, function(object, value) { + + var id = object.attr('id').replace("order_line_items_attributes_", "").replace("_quantity", ""); + id = "#order_line_items_attributes_" + id + "_id"; + + jQuery.ajax({ + type: "POST", + url: "/admin/orders/" + $('input#order_number').val() + "/line_items/" + $(id).val(), + data: ({_method: "put", "line_item[quantity]": value}), + success: function(html){ $('#order-form-wrapper').html(html)} + }); + + }); + }); diff --git a/spec/test_app/public/javascripts/admin/payments/new.js b/spec/test_app/public/javascripts/admin/payments/new.js new file mode 100644 index 0000000..bf164dd --- /dev/null +++ b/spec/test_app/public/javascripts/admin/payments/new.js @@ -0,0 +1,9 @@ +$(document).ready(function(){ + + $("#card_new").radioControlsVisibilityOfElement('#card_form'); + + $('select.jump_menu').change(function(){ + window.location = this.options[this.selectedIndex].value; + }); + +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/admin/unobtrusive_handlers.js b/spec/test_app/public/javascripts/admin/unobtrusive_handlers.js new file mode 100644 index 0000000..7b8ff31 --- /dev/null +++ b/spec/test_app/public/javascripts/admin/unobtrusive_handlers.js @@ -0,0 +1,15 @@ +$(document).ready(function(){ + + $(".select_properties_from_prototype").live("click", function(){ + $("#busy_indicator").show(); + var clicked_link = $(this); + jQuery.ajax({ dataType: 'script', url: clicked_link.attr("href"), type: 'get', + success: function(data){ + clicked_link.parent("td").parent("tr").hide(); + $("#busy_indicator").hide(); + } + }); + return false; + }); + +}); diff --git a/spec/test_app/public/javascripts/application.js b/spec/test_app/public/javascripts/application.js new file mode 100644 index 0000000..ca62ff5 --- /dev/null +++ b/spec/test_app/public/javascripts/application.js @@ -0,0 +1,12 @@ +(function($){ + $(document).ready(function(){ + + // Remove an item from the cart by setting its quantity to zero and posting the update form + $('form#updatecart a.delete').show().click(function(){ + $(this).parents('tr').find('input.line_item_quantity').val(0); + $(this).parents('form').submit(); + return false; + }); + + }); +})(jQuery); diff --git a/spec/test_app/public/javascripts/calculator.js b/spec/test_app/public/javascripts/calculator.js new file mode 100644 index 0000000..cfad998 --- /dev/null +++ b/spec/test_app/public/javascripts/calculator.js @@ -0,0 +1,15 @@ +$j(function() { + var original_calc_type = $j('#calc-type').attr('value'); + $j('div#calculator-settings-warning').hide(); + $j('#calc-type').change(function() { + if ($j('#calc-type').attr('value') == original_calc_type) { + $j('div.calculator-settings').show(); + $j('div#calculator-settings-warning').hide(); + $j('.calculator-settings input').removeAttr('disabled'); + } else { + $j('div.calculator-settings').hide(); + $j('div#calculator-settings-warning').show(); + $j('.calculator-settings input').attr('disabled', 'disabled'); + } + }); +}) diff --git a/spec/test_app/public/javascripts/checkout.js b/spec/test_app/public/javascripts/checkout.js new file mode 100644 index 0000000..02dce4c --- /dev/null +++ b/spec/test_app/public/javascripts/checkout.js @@ -0,0 +1,75 @@ +(function($){ + $(document).ready(function(){ + + $('#checkout_form_address').validate(); + + var get_states = function(region){ + var country = $('span#' + region + 'country :only-child').val(); + return state_mapper[country]; + } + + var update_state = function(region) { + var states = get_states(region); + + var state_select = $('span#' + region + 'state select'); + var state_input = $('span#' + region + 'state input'); + + if(states) { + var selected = state_select.val(); + state_select.html(''); + var states_with_blank = [["",""]].concat(states); + $.each(states_with_blank, function(pos,id_nm) { + var opt = $(document.createElement('option')) + .attr('value', id_nm[0]) + .html(id_nm[1]); + if(selected==id_nm[0]){ + opt.attr('selected', 'selected'); + } + state_select.append(opt); + }); + state_select.removeAttr('disabled').show(); + state_input.hide().attr('disabled', 'disabled'); + + } else { + state_input.removeAttr('disabled').show(); + state_select.hide().attr('disabled', 'disabled'); + } + + }; + + // Show fields for the selected payment method + $("input[type='radio'][name='order[payments_attributes][][payment_method_id]']").click(function(){ + $('#payment-methods li').hide(); + if(this.checked){ $('#payment_method_'+this.value).show(); } + }).triggerHandler('click'); + + $('span#bcountry select').change(function() { update_state('b'); }); + $('span#scountry select').change(function() { update_state('s'); }); + update_state('b'); + update_state('s'); + + $('input#order_use_billing').click(function() { + if($(this).is(':checked')) { + $('#shipping .inner input, #shipping .inner select, #shipping .inner label, #shipping .inner .req').hide(); + $('#shipping .inner input, #shipping .inner select').attr('disabled', 'disabled'); + } else { + $('#shipping .inner input, #shipping .inner select, #shipping .inner label, #shipping .inner .req').show(); + $('#shipping .inner input, #shipping .inner select').removeAttr('disabled', 'disabled'); + + //only want to enable relevant field + if(get_states('s')){ + $('span#sstate input').hide().attr('disabled', 'disabled'); + }else{ + $('span#sstate select').hide().attr('disabled', 'disabled'); + } + + } + }).triggerHandler('click'); + + $('form.edit_checkout').submit(function() { + $(this).find(':submit, :image').attr('disabled', true).removeClass('primary').addClass('disabled'); + }); + + + }); +})(jQuery); diff --git a/spec/test_app/public/javascripts/datepicker.js b/spec/test_app/public/javascripts/datepicker.js new file mode 100644 index 0000000..a62a010 --- /dev/null +++ b/spec/test_app/public/javascripts/datepicker.js @@ -0,0 +1,1445 @@ +/* + DatePicker v4.4 by frequency-decoder.com + + Released under a creative commons Attribution-ShareAlike 2.5 license (http://creativecommons.org/licenses/by-sa/2.5/) + + Please credit frequency-decoder in any derivative work - thanks. + + You are free: + + * to copy, distribute, display, and perform the work + * to make derivative works + * to make commercial use of the work + + Under the following conditions: + + by Attribution. + -------------- + You must attribute the work in the manner specified by the author or licensor. + + sa + -- + Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. + + * For any reuse or distribution, you must make clear to others the license terms of this work. + * Any of these conditions can be waived if you get permission from the copyright holder. +*/ +var datePickerController; + +(function() { + +// Detect the browser language +datePicker.languageinfo = navigator.language ? navigator.language : navigator.userLanguage; +datePicker.languageinfo = datePicker.languageinfo ? datePicker.languageinfo.toLowerCase().replace(/-[a-z]+$/, "") : 'en'; + +// Load the appropriate language file +var scriptFiles = document.getElementsByTagName('head')[0].getElementsByTagName('script'); +var loc = scriptFiles[scriptFiles.length - 1].src.substr(0, scriptFiles[scriptFiles.length - 1].src.lastIndexOf("/")) + "/lang/" + datePicker.languageinfo + ".js"; + +var script = document.createElement('script'); +script.type = "text/javascript"; +script.src = loc; +script.setAttribute("charset", "utf-8"); +/*@cc_on +/*@if(@_win32) + var bases = document.getElementsByTagName('base'); + if (bases.length && bases[0].childNodes.length) { + bases[0].appendChild(script); + } else { + document.getElementsByTagName('head')[0].appendChild(script); + }; +@else @*/ +document.getElementsByTagName('head')[0].appendChild(script); +/*@end +@*/ +script = null; + +// Defaults should the locale file not load +datePicker.months = ["January","February","March","April","May","June","July","August","September","October","November","December"]; +datePicker.fullDay = ["Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"]; +datePicker.titles = ["Previous month","Next month","Previous year","Next year", "Today", "Show Calendar"]; + +datePicker.getDaysPerMonth = function(nMonth, nYear) { + nMonth = (nMonth + 12) % 12; + return (((0 == (nYear%4)) && ((0 != (nYear%100)) || (0 == (nYear%400)))) && nMonth == 1) ? 29: [31,28,31,30,31,30,31,31,30,31,30,31][nMonth]; +}; + +function datePicker(options) { + + this.defaults = {}; + for(opt in options) { this[opt] = this.defaults[opt] = options[opt]; }; + + this.date = new Date(); + this.yearinc = 1; + this.timer = null; + this.pause = 1000; + this.timerSet = false; + this.fadeTimer = null; + this.interval = new Date(); + this.firstDayOfWeek = this.defaults.firstDayOfWeek = this.dayInc = this.monthInc = this.yearInc = this.opacity = this.opacityTo = 0; + this.dateSet = null; + this.visible = false; + this.disabledDates = []; + this.enabledDates = []; + this.nbsp = String.fromCharCode( 160 ); + var o = this; + + o.events = { + onblur:function(e) { + o.removeKeyboardEvents(); + }, + onfocus:function(e) { + o.addKeyboardEvents(); + }, + onkeydown: function (e) { + o.stopTimer(); + if(!o.visible) return false; + + if(e == null) e = document.parentWindow.event; + var kc = e.keyCode ? e.keyCode : e.charCode; + + if( kc == 13 ) { + // close (return) + var td = document.getElementById(o.id + "-date-picker-hover"); + if(!td || td.className.search(/out-of-range|day-disabled/) != -1) return o.killEvent(e); + o.returnFormattedDate(); + o.hide(); + return o.killEvent(e); + } else if(kc == 27) { + // close (esc) + o.hide(); + return o.killEvent(e); + } else if(kc == 32 || kc == 0) { + // today (space) + o.date = new Date(); + o.updateTable(); + return o.killEvent(e); + }; + + // Internet Explorer fires the keydown event faster than the JavaScript engine can + // update the interface. The following attempts to fix this. + /*@cc_on + @if(@_win32) + if(new Date().getTime() - o.interval.getTime() < 100) return o.killEvent(e); + o.interval = new Date(); + @end + @*/ + + if ((kc > 49 && kc < 56) || (kc > 97 && kc < 104)) { + if (kc > 96) kc -= (96-48); + kc -= 49; + o.firstDayOfWeek = (o.firstDayOfWeek + kc) % 7; + o.updateTable(); + return o.killEvent(e); + }; + + if ( kc < 37 || kc > 40 ) return true; + + var d = new Date( o.date ).valueOf(); + + if ( kc == 37 ) { + // ctrl + left = previous month + if( e.ctrlKey ) { + d = new Date( o.date ); + d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth() - 1,d.getFullYear())) ); + d.setMonth( d.getMonth() - 1 ); + } else { + d = new Date( o.date.getFullYear(), o.date.getMonth(), o.date.getDate() - 1 ); + }; + } else if ( kc == 39 ) { + // ctrl + right = next month + if( e.ctrlKey ) { + d = new Date( o.date ); + d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth() + 1,d.getFullYear())) ); + d.setMonth( d.getMonth() + 1 ); + } else { + d = new Date( o.date.getFullYear(), o.date.getMonth(), o.date.getDate() + 1 ); + }; + } else if ( kc == 38 ) { + // ctrl + up = next year + if( e.ctrlKey ) { + d = new Date( o.date ); + d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth(),d.getFullYear() + 1)) ); + d.setFullYear( d.getFullYear() + 1 ); + } else { + d = new Date( o.date.getFullYear(), o.date.getMonth(), o.date.getDate() - 7 ); + }; + } else if ( kc == 40 ) { + // ctrl + down = prev year + if( e.ctrlKey ) { + d = new Date( o.date ); + d.setDate( Math.min(d.getDate(), datePicker.getDaysPerMonth(d.getMonth(),d.getFullYear() - 1)) ); + d.setFullYear( d.getFullYear() - 1 ); + } else { + d = new Date( o.date.getFullYear(), o.date.getMonth(), o.date.getDate() + 7 ); + }; + }; + + var tmpDate = new Date(d); + + if(o.outOfRange(tmpDate)) return o.killEvent(e); + + var cacheDate = new Date(o.date); + o.date = tmpDate; + + if(cacheDate.getFullYear() != o.date.getFullYear() || cacheDate.getMonth() != o.date.getMonth()) o.updateTable(); + else { + o.disableTodayButton(); + var tds = o.table.getElementsByTagName('td'); + var txt; + var start = o.date.getDate() - 6; + if(start < 0) start = 0; + + for(var i = start, td; td = tds[i]; i++) { + txt = Number(td.firstChild.nodeValue); + if(isNaN(txt) || txt != o.date.getDate()) continue; + o.removeHighlight(); + td.id = o.id + "-date-picker-hover"; + td.className = td.className.replace(/date-picker-hover/g, "") + " date-picker-hover"; + }; + }; + return o.killEvent(e); + }, + gotoToday: function(e) { + o.date = new Date(); + o.updateTable(); + return o.killEvent(e); + }, + onmousedown: function(e) { + if ( e == null ) e = document.parentWindow.event; + var el = e.target != null ? e.target : e.srcElement; + + var found = false; + while(el.parentNode) { + if(el.id && (el.id == "fd-"+o.id || el.id == "fd-but-"+o.id)) { + found = true; + break; + }; + try { + el = el.parentNode; + } catch(err) { + break; + }; + }; + if(found) return true; + o.stopTimer(); + datePickerController.hideAll(); + }, + onmouseover: function(e) { + o.stopTimer(); + var txt = this.firstChild.nodeValue; + if(this.className == "out-of-range" || txt.search(/^[\d]+$/) == -1) return; + + o.removeHighlight(); + + this.id = o.id+"-date-picker-hover"; + this.className = this.className.replace(/date-picker-hover/g, "") + " date-picker-hover"; + + o.date.setDate(this.firstChild.nodeValue); + o.disableTodayButton(); + }, + onclick: function(e) { + if(o.opacity != o.opacityTo || this.className.search(/out-of-range|day-disabled/) != -1) return false; + if ( e == null ) e = document.parentWindow.event; + var el = e.target != null ? e.target : e.srcElement; + while ( el.nodeType != 1 ) el = el.parentNode; + var d = new Date( o.date ); + var txt = el.firstChild.data; + if(txt.search(/^[\d]+$/) == -1) return; + var n = Number( txt ); + if(isNaN(n)) { return true; }; + d.setDate( n ); + o.date = d; + o.returnFormattedDate(); + if(!o.staticPos) o.hide(); + o.stopTimer(); + return o.killEvent(e); + }, + incDec: function(e) { + if ( e == null ) e = document.parentWindow.event; + var el = e.target != null ? e.target : e.srcElement; + + if(el && el.className && el.className.search('fd-disabled') != -1) { return false; } + datePickerController.addEvent(document, "mouseup", o.events.clearTimer); + o.timerInc = 800; + o.dayInc = arguments[1]; + o.yearInc = arguments[2]; + o.monthInc = arguments[3]; + o.timerSet = true; + + o.updateTable(); + return true; + }, + clearTimer: function(e) { + o.stopTimer(); + o.timerInc = 1000; + o.yearInc = 0; + o.monthInc = 0; + o.dayInc = 0; + datePickerController.removeEvent(document, "mouseup", o.events.clearTimer); + } + }; + o.stopTimer = function() { + o.timerSet = false; + window.clearTimeout(o.timer); + }; + o.removeHighlight = function() { + if(document.getElementById(o.id+"-date-picker-hover")) { + document.getElementById(o.id+"-date-picker-hover").className = document.getElementById(o.id+"-date-picker-hover").className.replace("date-picker-hover", ""); + document.getElementById(o.id+"-date-picker-hover").id = ""; + }; + }; + o.reset = function() { + for(def in o.defaults) { o[def] = o.defaults[def]; }; + }; + o.setOpacity = function(op) { + o.div.style.opacity = op/100; + o.div.style.filter = 'alpha(opacity=' + op + ')'; + o.opacity = op; + }; + o.fade = function() { + window.clearTimeout(o.fadeTimer); + o.fadeTimer = null; + delete(o.fadeTimer); + + var diff = Math.round(o.opacity + ((o.opacityTo - o.opacity) / 4)); + + o.setOpacity(diff); + + if(Math.abs(o.opacityTo - diff) > 3 && !o.noTransparency) { + o.fadeTimer = window.setTimeout(o.fade, 50); + } else { + o.setOpacity(o.opacityTo); + if(o.opacityTo == 0) { + o.div.style.display = "none"; + o.visible = false; + } else { + o.visible = true; + }; + }; + }; + o.killEvent = function(e) { + e = e || document.parentWindow.event; + + if(e.stopPropagation) { + e.stopPropagation(); + e.preventDefault(); + }; + + /*@cc_on + @if(@_win32) + e.cancelBubble = true; + e.returnValue = false; + @end + @*/ + return false; + }; + o.getElem = function() { + return document.getElementById(o.id.replace(/^fd-/, '')) || false; + }; + o.setRangeLow = function(range) { + if(String(range).search(/^(\d\d?\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) range = ''; + o.low = o.defaults.low = range; + if(o.staticPos) o.updateTable(true); + }; + o.setRangeHigh = function(range) { + if(String(range).search(/^(\d\d?\d\d)(0[1-9]|1[012])(0[1-9]|[12][0-9]|3[01])$/) == -1) range = ''; + o.high = o.defaults.high = range; + if(o.staticPos) o.updateTable(true); + }; + o.setDisabledDays = function(dayArray) { + o.disableDays = o.defaults.disableDays = dayArray; + if(o.staticPos) o.updateTable(true); + }; + o.setDisabledDates = function(dateArray) { + var fin = []; + for(var i = dateArray.length; i-- ;) { + if(dateArray[i].match(/^(\d\d\d\d|\*\*\*\*)(0[1-9]|1[012]|\*\*)(0[1-9]|[12][0-9]|3[01])$/) != -1) fin[fin.length] = dateArray[i]; + }; + if(fin.length) { + o.disabledDates = fin; + o.enabledDates = []; + if(o.staticPos) o.updateTable(true); + }; + }; + o.setEnabledDates = function(dateArray) { + var fin = []; + for(var i = dateArray.length; i-- ;) { + if(dateArray[i].match(/^(\d\d\d\d|\*\*\*\*)(0[1-9]|1[012]|\*\*)(0[1-9]|[12][0-9]|3[01]|\*\*)$/) != -1 && dateArray[i] != "********") fin[fin.length] = dateArray[i]; + }; + if(fin.length) { + o.disabledDates = []; + o.enabledDates = fin; + if(o.staticPos) o.updateTable(true); + }; + }; + o.getDisabledDates = function(y, m) { + if(o.enabledDates.length) return o.getEnabledDates(y, m); + var obj = {}; + var d = datePicker.getDaysPerMonth(m - 1, y); + m = m < 10 ? "0" + String(m) : m; + for(var i = o.disabledDates.length; i-- ;) { + var tmp = o.disabledDates[i].replace("****", y).replace("**", m); + if(tmp < Number(String(y)+m+"01") || tmp > Number(y+String(m)+d)) continue; + obj[tmp] = 1; + }; + return obj; + }; + o.getEnabledDates = function(y, m) { + var obj = {}; + var d = datePicker.getDaysPerMonth(m - 1, y); + m = m < 10 ? "0" + String(m) : m; + var day,tmp,de,me,ye,disabled; + for(var dd = 1; dd <= d; dd++) { + day = dd < 10 ? "0" + String(dd) : dd; + disabled = true; + for(var i = o.enabledDates.length; i-- ;) { + tmp = o.enabledDates[i]; + ye = String(o.enabledDates[i]).substr(0,4); + me = String(o.enabledDates[i]).substr(4,2); + de = String(o.enabledDates[i]).substr(6,2); + + if(ye == y && me == m && de == day) { + disabled = false; + break; + } + + if(ye == "****" || me == "**" || de == "**") { + if(ye == "****") tmp = tmp.replace(/^\*\*\*\*/, y); + if(me == "**") tmp = tmp = tmp.substr(0,4) + String(m) + tmp.substr(6,2); + if(de == "**") tmp = tmp.replace(/\*\*/, day); + + if(tmp == String(y + String(m) + day)) { + disabled = false; + break; + }; + }; + }; + if(disabled) obj[String(y + String(m) + day)] = 1; + }; + return obj; + }; + o.setFirstDayOfWeek = function(e) { + if ( e == null ) e = document.parentWindow.event; + var elem = e.target != null ? e.target : e.srcElement; + if(elem.tagName.toLowerCase() != "th") { + while(elem.tagName.toLowerCase() != "th") elem = elem.parentNode; + }; + var cnt = 0; + while(elem.previousSibling) { + elem = elem.previousSibling; + if(elem.tagName.toLowerCase() == "th") cnt++; + }; + o.firstDayOfWeek = (o.firstDayOfWeek + cnt) % 7; + o.updateTableHeaders(); + return o.killEvent(e); + }; + o.truePosition = function(element) { + var pos = o.cumulativeOffset(element); + if(window.opera) { return pos; } + var iebody = (document.compatMode && document.compatMode != "BackCompat")? document.documentElement : document.body; + var dsocleft = document.all ? iebody.scrollLeft : window.pageXOffset; + var dsoctop = document.all ? iebody.scrollTop : window.pageYOffset; + var posReal = o.realOffset(element); + return [pos[0] - posReal[0] + dsocleft, pos[1] - posReal[1] + dsoctop]; + }; + o.realOffset = function(element) { + var t = 0, l = 0; + do { + t += element.scrollTop || 0; + l += element.scrollLeft || 0; + element = element.parentNode; + } while (element); + return [l, t]; + }; + o.cumulativeOffset = function(element) { + var t = 0, l = 0; + do { + t += element.offsetTop || 0; + l += element.offsetLeft || 0; + element = element.offsetParent; + } while (element); + return [l, t]; + }; + o.resize = function() { + if(!o.created || !o.getElem()) return; + + o.div.style.visibility = "hidden"; + if(!o.staticPos) { o.div.style.left = o.div.style.top = "0px"; } + o.div.style.display = "block"; + + var osh = o.div.offsetHeight; + var osw = o.div.offsetWidth; + + o.div.style.visibility = "visible"; + o.div.style.display = "none"; + + if(!o.staticPos) { + var elem = document.getElementById('fd-but-' + o.id); + var pos = o.truePosition(elem); + var trueBody = (document.compatMode && document.compatMode!="BackCompat") ? document.documentElement : document.body; + var scrollTop = window.devicePixelRatio || window.opera ? 0 : trueBody.scrollTop; + var scrollLeft = window.devicePixelRatio || window.opera ? 0 : trueBody.scrollLeft; + + if(parseInt(trueBody.clientWidth+scrollLeft) < parseInt(osw+pos[0])) { + o.div.style.left = Math.abs(parseInt((trueBody.clientWidth+scrollLeft) - osw)) + "px"; + } else { + o.div.style.left = pos[0] + "px"; + }; + + if(parseInt(trueBody.clientHeight+scrollTop) < parseInt(osh+pos[1]+elem.offsetHeight+2)) { + o.div.style.top = Math.abs(parseInt(pos[1] - (osh + 2))) + "px"; + } else { + o.div.style.top = Math.abs(parseInt(pos[1] + elem.offsetHeight + 2)) + "px"; + }; + }; + /*@cc_on + @if(@_jscript_version <= 5.6) + if(o.staticPos) return; + o.iePopUp.style.top = o.div.style.top; + o.iePopUp.style.left = o.div.style.left; + o.iePopUp.style.width = osw + "px"; + o.iePopUp.style.height = (osh - 2) + "px"; + @end + @*/ + }; + o.equaliseDates = function() { + var clearDayFound = false; + var tmpDate; + for(var i = o.low; i <= o.high; i++) { + tmpDate = String(i); + if(!o.disableDays[new Date(tmpDate.substr(0,4), tmpDate.substr(6,2), tmpDate.substr(4,2)).getDay() - 1]) { + clearDayFound = true; + break; + }; + }; + if(!clearDayFound) o.disableDays = o.defaults.disableDays = [0,0,0,0,0,0,0]; + }; + o.outOfRange = function(tmpDate) { + if(!o.low && !o.high) return false; + + var level = false; + if(!tmpDate) { + level = true; + tmpDate = o.date; + }; + + var d = (tmpDate.getDate() < 10) ? "0" + tmpDate.getDate() : tmpDate.getDate(); + var m = ((tmpDate.getMonth() + 1) < 10) ? "0" + (tmpDate.getMonth() + 1) : tmpDate.getMonth() + 1; + var y = tmpDate.getFullYear(); + var dt = String(y)+String(m)+String(d); + + if(o.low && parseInt(dt) < parseInt(o.low)) { + if(!level) return true; + o.date = new Date(o.low.substr(0,4), o.low.substr(4,2)-1, o.low.substr(6,2), 5, 0, 0); + return false; + }; + if(o.high && parseInt(dt) > parseInt(o.high)) { + if(!level) return true; + o.date = new Date( o.high.substr(0,4), o.high.substr(4,2)-1, o.high.substr(6,2), 5, 0, 0); + }; + return false; + }; + o.createButton = function() { + if(o.staticPos) { return; }; + + var but; + + if(!document.getElementById("fd-but-" + o.id)) { + var inp = o.getElem(); + + but = document.createElement('a'); + but.href = "#"; + + var span = document.createElement('span'); + span.appendChild(document.createTextNode(String.fromCharCode( 160 ))); + + but.className = "date-picker-control"; + but.title = (typeof(fdLocale) == "object" && options.locale && fdLocale.titles.length > 5) ? fdLocale.titles[5] : ""; + + but.id = "fd-but-" + o.id; + but.appendChild(span); + + if(inp.nextSibling) { + inp.parentNode.insertBefore(but, inp.nextSibling); + } else { + inp.parentNode.appendChild(but); + }; + } else { + but = document.getElementById("fd-but-" + o.id); + }; + + but.onclick = but.onpress = function(e) { + e = e || window.event; + var inpId = this.id.replace('fd-but-',''); + try { var dp = datePickerController.getDatePicker(inpId); } catch(err) { return false; }; + + if(e.type == "press") { + var kc = e.keyCode != null ? e.keyCode : e.charCode; + if(kc != 13) { return true; }; + if(dp.visible) { + hideAll(); + return false; + }; + }; + + if(!dp.visible) { + datePickerController.hideAll(inpId); + dp.show(); + } else { + datePickerController.hideAll(); + }; + return false; + }; + but = null; + }, + o.create = function() { + + function createTH(details) { + var th = document.createElement('th'); + if(details.thClassName) th.className = details.thClassName; + if(details.colspan) { + /*@cc_on + /*@if (@_win32) + th.setAttribute('colSpan',details.colspan); + @else @*/ + th.setAttribute('colspan',details.colspan); + /*@end + @*/ + }; + /*@cc_on + /*@if (@_win32) + th.unselectable = "on"; + /*@end@*/ + return th; + }; + + function createThAndButton(tr, obj) { + for(var i = 0, details; details = obj[i]; i++) { + var th = createTH(details); + tr.appendChild(th); + var but = document.createElement('span'); + but.className = details.className; + but.id = o.id + details.id; + but.appendChild(document.createTextNode(details.text)); + but.title = details.title || ""; + if(details.onmousedown) but.onmousedown = details.onmousedown; + if(details.onclick) but.onclick = details.onclick; + if(details.onmouseout) but.onmouseout = details.onmouseout; + th.appendChild(but); + }; + }; + + /*@cc_on + @if(@_jscript_version <= 5.6) + if(!document.getElementById("iePopUpHack")) { + o.iePopUp = document.createElement('iframe'); + o.iePopUp.src = "javascript:'';"; + o.iePopUp.setAttribute('className','iehack'); + o.iePopUp.scrolling="no"; + o.iePopUp.frameBorder="0"; + o.iePopUp.name = o.iePopUp.id = "iePopUpHack"; + document.body.appendChild(o.iePopUp); + } else { + o.iePopUp = document.getElementById("iePopUpHack"); + }; + @end + @*/ + + if(typeof(fdLocale) == "object" && o.locale) { + datePicker.titles = fdLocale.titles; + datePicker.months = fdLocale.months; + datePicker.fullDay = fdLocale.fullDay; + // Optional parameters + if(fdLocale.dayAbbr) datePicker.dayAbbr = fdLocale.dayAbbr; + if(fdLocale.firstDayOfWeek) o.firstDayOfWeek = o.defaults.firstDayOfWeek = fdLocale.firstDayOfWeek; + }; + + o.div = document.createElement('div'); + o.div.style.zIndex = 9999; + o.div.id = "fd-"+o.id; + o.div.className = "datePicker"; + + if(!o.staticPos) { + document.getElementsByTagName('body')[0].appendChild(o.div); + } else { + elem = o.getElem(); + if(!elem) { + o.div = null; + return; + }; + o.div.className += " staticDP"; + o.div.setAttribute("tabIndex", "0"); + o.div.onfocus = o.events.onfocus; + o.div.onblur = o.events.onblur; + elem.parentNode.insertBefore(o.div, elem.nextSibling); + if(o.hideInput && elem.type && elem.type == "text") elem.setAttribute("type", "hidden"); + }; + + //var nbsp = String.fromCharCode( 160 ); + var tr, row, col, tableHead, tableBody; + + o.table = document.createElement('table'); + o.div.appendChild( o.table ); + + tableHead = document.createElement('thead'); + o.table.appendChild( tableHead ); + + tr = document.createElement('tr'); + tableHead.appendChild(tr); + + // Title Bar + o.titleBar = createTH({thClassName:"date-picker-title", colspan:7}); + tr.appendChild( o.titleBar ); + tr = null; + + var span = document.createElement('span'); + span.className = "month-display"; + o.titleBar.appendChild(span); + + span = document.createElement('span'); + span.className = "year-display"; + o.titleBar.appendChild(span); + + span = null; + + tr = document.createElement('tr'); + tableHead.appendChild(tr); + + createThAndButton(tr, [{className:"prev-but", id:"-prev-year-but", text:"\u00AB", title:datePicker.titles[2], onmousedown:function(e) { o.events.incDec(e,0,-1,0); }, onmouseout:o.events.clearTimer },{className:"prev-but", id:"-prev-month-but", text:"\u2039", title:datePicker.titles[0], onmousedown:function(e) { o.events.incDec(e,0,0,-1); }, onmouseout:o.events.clearTimer },{colspan:3, className:"today-but", id:"-today-but", text:datePicker.titles.length > 4 ? datePicker.titles[4] : "Today", onclick:o.events.gotoToday},{className:"next-but", id:"-next-month-but", text:"\u203A", title:datePicker.titles[1], onmousedown:function(e) { o.events.incDec(e,0,0,1); }, onmouseout:o.events.clearTimer },{className:"next-but", id:"-next-year-but", text:"\u00BB", title:datePicker.titles[3], onmousedown:function(e) { o.events.incDec(e,0,1,0); }, onmouseout:o.events.clearTimer }]); + + tableBody = document.createElement('tbody'); + o.table.appendChild( tableBody ); + + for(var rows = 0; rows < 7; rows++) { + row = document.createElement('tr'); + + if(rows != 0) tableBody.appendChild(row); + else tableHead.appendChild(row); + + for(var cols = 0; cols < 7; cols++) { + col = (rows == 0) ? document.createElement('th') : document.createElement('td'); + + row.appendChild(col); + if(rows != 0) { + col.appendChild(document.createTextNode(o.nbsp)); + col.onmouseover = o.events.onmouseover; + col.onclick = o.events.onclick; + } else { + col.className = "date-picker-day-header"; + col.scope = "col"; + }; + col = null; + }; + row = null; + }; + + // Table headers + var but; + var ths = o.table.getElementsByTagName('thead')[0].getElementsByTagName('tr')[2].getElementsByTagName('th'); + for ( var y = 0; y < 7; y++ ) { + if(y > 0) { + but = document.createElement("span"); + but.className = "fd-day-header"; + but.onclick = ths[y].onclick = o.setFirstDayOfWeek; + but.appendChild(document.createTextNode(o.nbsp)); + ths[y].appendChild(but); + but = null; + } else { + ths[y].appendChild(document.createTextNode(o.nbsp)); + }; + }; + + o.ths = o.table.getElementsByTagName('thead')[0].getElementsByTagName('tr')[2].getElementsByTagName('th'); + o.trs = o.table.getElementsByTagName('tbody')[0].getElementsByTagName('tr'); + + o.updateTableHeaders(); + + tableBody = tableHead = tr = createThAndButton = createTH = null; + + if(o.low && o.high && (o.high - o.low < 7)) { o.equaliseDates(); }; + + o.created = true; + + if(o.staticPos) { + var yyN = document.getElementById(o.id); + datePickerController.addEvent(yyN, "change", o.changeHandler); + if(o.splitDate) { + var mmN = document.getElementById(o.id+'-mm'); + var ddN = document.getElementById(o.id+'-dd'); + datePickerController.addEvent(mmN, "change", o.changeHandler); + datePickerController.addEvent(ddN, "change", o.changeHandler); + }; + + o.show(); + } else { + o.createButton(); + o.resize(); + o.fade(); + }; + }; + o.changeHandler = function() { + o.setDateFromInput(); + o.updateTable(); + }; + o.setDateFromInput = function() { + function m2c(val) { + return String(val).length < 2 ? "00".substring(0, 2 - String(val).length) + String(val) : val; + }; + + o.dateSet = null; + + var elem = o.getElem(); + if(!elem) return; + + if(!o.splitDate) { + var date = datePickerController.dateFormat(elem.value, o.format.search(/m-d-y/i) != -1); + } else { + var mmN = document.getElementById(o.id+'-mm'); + var ddN = document.getElementById(o.id+'-dd'); + var tm = parseInt(mmN.tagName.toLowerCase() == "input" ? mmN.value : mmN.options[mmN.selectedIndex].value, 10); + var td = parseInt(ddN.tagName.toLowerCase() == "input" ? ddN.value : ddN.options[ddN.selectedIndex].value, 10); + var ty = parseInt(elem.tagName.toLowerCase() == "input" ? elem.value : elem.options[elem.selectedIndex || 0].value, 10); + var date = datePickerController.dateFormat(tm + "/" + td + "/" + ty, true); + }; + + var badDate = false; + if(!date) { + badDate = true; + date = String(new Date().getFullYear()) + m2c(new Date().getMonth()+1) + m2c(new Date().getDate()); + }; + + var d,m,y; + y = Number(date.substr(0, 4)); + m = Number(date.substr(4, 2)) - 1; + d = Number(date.substr(6, 2)); + + var dpm = datePicker.getDaysPerMonth(m, y); + if(d > dpm) d = dpm; + + if(new Date(y, m, d) == 'Invalid Date' || new Date(y, m, d) == 'NaN') { + badDate = true; + o.date = new Date(); + o.date.setHours(5); + return; + }; + + o.date = new Date(y, m, d); + o.date.setHours(5); + + if(!badDate) o.dateSet = new Date(o.date); + m2c = null; + }; + o.setSelectIndex = function(elem, indx) { + var len = elem.options.length; + indx = Number(indx); + for(var opt = 0; opt < len; opt++) { + if(elem.options[opt].value == indx) { + elem.selectedIndex = opt; + return; + }; + }; + }, + o.returnFormattedDate = function() { + + var elem = o.getElem(); + if(!elem) return; + + var d = (o.date.getDate() < 10) ? "0" + o.date.getDate() : o.date.getDate(); + var m = ((o.date.getMonth() + 1) < 10) ? "0" + (o.date.getMonth() + 1) : o.date.getMonth() + 1; + var yyyy = o.date.getFullYear(); + var disabledDates = o.getDisabledDates(yyyy, m); + var weekDay = ( o.date.getDay() + 6 ) % 7; + + if(!(o.disableDays[weekDay] || String(yyyy)+m+d in disabledDates)) { + + if(o.splitDate) { + var ddE = document.getElementById(o.id+"-dd"); + var mmE = document.getElementById(o.id+"-mm"); + + if(ddE.tagName.toLowerCase() == "input") { ddE.value = d; } + else { o.setSelectIndex(ddE, d); /*ddE.selectedIndex = d - 1;*/ }; + + if(mmE.tagName.toLowerCase() == "input") { mmE.value = m; } + else { o.setSelectIndex(mmE, m); /*mmE.selectedIndex = m - 1;*/ }; + + if(elem.tagName.toLowerCase() == "input") elem.value = yyyy; + else { + o.setSelectIndex(elem, yyyy); /* + for(var opt = 0; opt < elem.options.length; opt++) { + if(elem.options[opt].value == yyyy) { + elem.selectedIndex = opt; + break; + }; + }; + */ + }; + } else { + elem.value = o.format.replace('y',yyyy).replace('m',m).replace('d',d).replace(/-/g,o.divider); + }; + if(!elem.type || elem.type && elem.type != "hidden"){ elem.focus(); } + if(o.staticPos) { + o.dateSet = new Date( o.date ); + o.updateTable(); + }; + + // Programmatically fire the onchange event + if(document.createEvent) { + var onchangeEvent = document.createEvent('HTMLEvents'); + onchangeEvent.initEvent('change', true, false); + elem.dispatchEvent(onchangeEvent); + } else if(document.createEventObject) { + elem.fireEvent('onchange'); + }; + }; + }; + o.disableTodayButton = function() { + var today = new Date(); + document.getElementById(o.id + "-today-but").className = document.getElementById(o.id + "-today-but").className.replace("fd-disabled", ""); + if(o.outOfRange(today) || (o.date.getDate() == today.getDate() && o.date.getMonth() == today.getMonth() && o.date.getFullYear() == today.getFullYear())) { + document.getElementById(o.id + "-today-but").className += " fd-disabled"; + document.getElementById(o.id + "-today-but").onclick = null; + } else { + document.getElementById(o.id + "-today-but").onclick = o.events.gotoToday; + }; + }; + o.updateTableHeaders = function() { + var d, but; + var ths = o.ths; + for ( var y = 0; y < 7; y++ ) { + d = (o.firstDayOfWeek + y) % 7; + ths[y].title = datePicker.fullDay[d]; + + if(y > 0) { + but = ths[y].getElementsByTagName("span")[0]; + but.removeChild(but.firstChild); + but.appendChild(document.createTextNode(datePicker.dayAbbr ? datePicker.dayAbbr[d] : datePicker.fullDay[d].charAt(0))); + but.title = datePicker.fullDay[d]; + but = null; + } else { + ths[y].removeChild(ths[y].firstChild); + ths[y].appendChild(document.createTextNode(datePicker.dayAbbr ? datePicker.dayAbbr[d] : datePicker.fullDay[d].charAt(0))); + }; + }; + o.updateTable(); + }; + + o.updateTable = function(noCallback) { + + if(o.timerSet) { + var d = new Date(o.date); + d.setDate( Math.min(d.getDate()+o.dayInc, datePicker.getDaysPerMonth(d.getMonth()+o.monthInc,d.getFullYear()+o.yearInc)) ); + d.setMonth( d.getMonth() + o.monthInc ); + d.setFullYear( d.getFullYear() + o.yearInc ); + o.date = d; + }; + + if(!noCallback && "onupdate" in datePickerController && typeof(datePickerController.onupdate) == "function") datePickerController.onupdate(o); + + o.outOfRange(); + o.disableTodayButton(); + + // Set the tmpDate to the second day of this month (to avoid daylight savings time madness on Windows) + var tmpDate = new Date( o.date.getFullYear(), o.date.getMonth(), 2 ); + tmpDate.setHours(5); + + var tdm = tmpDate.getMonth(); + var tdy = tmpDate.getFullYear(); + + // Do the disableDates for this year and month + var disabledDates = o.getDisabledDates(o.date.getFullYear(), o.date.getMonth() + 1); + + var today = new Date(); + + // Previous buttons out of range + var b = document.getElementById(o.id + "-prev-year-but"); + b.className = b.className.replace("fd-disabled", ""); + if(o.outOfRange(new Date((tdy - 1), Number(tdm), datePicker.getDaysPerMonth(Number(tdm), tdy-1)))) { + b.className += " fd-disabled"; + if(o.yearInc == -1) o.stopTimer(); + }; + + b = document.getElementById(o.id + "-prev-month-but") + b.className = b.className.replace("fd-disabled", ""); + if(o.outOfRange(new Date(tdy, (Number(tdm) - 1), datePicker.getDaysPerMonth(Number(tdm)-1, tdy)))) { + b.className += " fd-disabled"; + if(o.monthInc == -1) o.stopTimer(); + }; + + // Next buttons out of range + b= document.getElementById(o.id + "-next-year-but") + b.className = b.className.replace("fd-disabled", ""); + if(o.outOfRange(new Date((tdy + 1), Number(tdm), 1))) { + b.className += " fd-disabled"; + if(o.yearInc == 1) o.stopTimer(); + }; + + b = document.getElementById(o.id + "-next-month-but") + b.className = b.className.replace("fd-disabled", ""); + if(o.outOfRange(new Date(tdy, Number(tdm) + 1, 1))) { + b.className += " fd-disabled"; + if(o.monthInc == 1) o.stopTimer(); + }; + + b = null; + + var cd = o.date.getDate(); + var cm = o.date.getMonth(); + var cy = o.date.getFullYear(); + + // Title Bar + var span = o.titleBar.getElementsByTagName("span"); + while(span[0].firstChild) span[0].removeChild(span[0].firstChild); + while(span[1].firstChild) span[1].removeChild(span[1].firstChild); + span[0].appendChild(document.createTextNode(datePicker.months[cm] + o.nbsp)); + span[1].appendChild(document.createTextNode(cy)); + + tmpDate.setDate( 1 ); + + var dt, cName, td, tds, i; + var weekDay = ( tmpDate.getDay() + 6 ) % 7; + var firstColIndex = (( (weekDay - o.firstDayOfWeek) + 7 ) % 7) - 1; + var dpm = datePicker.getDaysPerMonth(cm, cy); + + var todayD = today.getDate(); + var todayM = today.getMonth(); + var todayY = today.getFullYear(); + + var c = "class"; + /*@cc_on + @if(@_win32) + c = "className"; + @end + @*/ + + var stub = String(tdy) + (String(tdm+1).length < 2 ? "0" + (tdm+1) : tdm+1); + + for(var row = 0; row < 6; row++) { + + tds = o.trs[row].getElementsByTagName('td'); + + for(var col = 0; col < 7; col++) { + + td = tds[col]; + td.removeChild(td.firstChild); + + td.setAttribute("id", ""); + td.setAttribute("title", ""); + + i = (row * 7) + col; + + if(i > firstColIndex && i <= (firstColIndex + dpm)) { + dt = i - firstColIndex; + + tmpDate.setDate(dt); + td.appendChild(document.createTextNode(dt)); + + if(o.outOfRange(tmpDate)) { + td.setAttribute(c, "out-of-range"); + } else { + + cName = []; + weekDay = ( tmpDate.getDay() + 6 ) % 7; + + if(dt == todayD && tdm == todayM && tdy == todayY) { + cName.push("date-picker-today"); + }; + + if(o.dateSet != null && o.dateSet.getDate() == dt && o.dateSet.getMonth() == tdm && o.dateSet.getFullYear() == tdy) { + cName.push("date-picker-selected-date"); + }; + + if(o.disableDays[weekDay] || stub + String(dt < 10 ? "0" + dt : dt) in disabledDates) { + cName.push("day-disabled"); + } else if(o.highlightDays[weekDay]) { + cName.push("date-picker-highlight"); + }; + + if(cd == dt) { + td.setAttribute("id", o.id + "-date-picker-hover"); + cName.push("date-picker-hover"); + }; + + cName.push("dm-" + dt + '-' + (tdm + 1) + " " + " dmy-" + dt + '-' + (tdm + 1) + '-' + tdy); + td.setAttribute(c, cName.join(' ')); + td.setAttribute("title", datePicker.months[cm] + o.nbsp + dt + "," + o.nbsp + cy); + }; + } else { + td.appendChild(document.createTextNode(o.nbsp)); + td.setAttribute(c, "date-picker-unused"); + }; + }; + }; + + if(o.timerSet) { + o.timerInc = 50 + Math.round(((o.timerInc - 50) / 1.8)); + o.timer = window.setTimeout(o.updateTable, o.timerInc); + }; + }; + o.addKeyboardEvents = function() { + datePickerController.addEvent(document, "keypress", o.events.onkeydown); + /*@cc_on + @if(@_win32) + datePickerController.removeEvent(document, "keypress", o.events.onkeydown); + datePickerController.addEvent(document, "keydown", o.events.onkeydown); + @end + @*/ + if(window.devicePixelRatio) { + datePickerController.removeEvent(document, "keypress", o.events.onkeydown); + datePickerController.addEvent(document, "keydown", o.events.onkeydown); + }; + }; + o.removeKeyboardEvents =function() { + datePickerController.removeEvent(document, "keypress", o.events.onkeydown); + datePickerController.removeEvent(document, "keydown", o.events.onkeydown); + }; + o.show = function() { + var elem = o.getElem(); + if(!elem || o.visible || elem.disabled) return; + + o.reset(); + o.setDateFromInput(); + o.updateTable(); + + if(!o.staticPos) o.resize(); + + datePickerController.addEvent(o.staticPos ? o.table : document, "mousedown", o.events.onmousedown); + + if(!o.staticPos) { o.addKeyboardEvents(); }; + + o.opacityTo = o.noTransparency ? 99 : 90; + o.div.style.display = "block"; + /*@cc_on + @if(@_jscript_version <= 5.6) + if(!o.staticPos) o.iePopUp.style.display = "block"; + @end + @*/ + + o.fade(); + o.visible = true; + }; + o.hide = function() { + if(!o.visible) return; + o.stopTimer(); + if(o.staticPos) return; + + datePickerController.removeEvent(document, "mousedown", o.events.onmousedown); + datePickerController.removeEvent(document, "mouseup", o.events.clearTimer); + o.removeKeyboardEvents(); + + /*@cc_on + @if(@_jscript_version <= 5.6) + o.iePopUp.style.display = "none"; + @end + @*/ + + o.opacityTo = 0; + o.fade(); + o.visible = false; + var elem = o.getElem(); + if(!elem.type || elem.type && elem.type != "hidden") { elem.focus(); }; + }; + o.destroy = function() { + // Cleanup for Internet Explorer + datePickerController.removeEvent(o.staticPos ? o.table : document, "mousedown", o.events.onmousedown); + datePickerController.removeEvent(document, "mouseup", o.events.clearTimer); + o.removeKeyboardEvents(); + + if(o.staticPos) { + var yyN = document.getElementById(o.id); + datePickerController.removeEvent(yyN, "change", o.changeHandler); + if(o.splitDate) { + var mmN = document.getElementById(o.id+'-mm'); + var ddN = document.getElementById(o.id+'-dd'); + + datePickerController.removeEvent(mmN, "change", o.changeHandler); + datePickerController.removeEvent(ddN, "change", o.changeHandler); + }; + o.div.onfocus = o.div.onblur = null; + }; + + var ths = o.table.getElementsByTagName("th"); + for(var i = 0, th; th = ths[i]; i++) { + th.onmouseover = th.onmouseout = th.onmousedown = th.onclick = null; + }; + + var tds = o.table.getElementsByTagName("td"); + for(var i = 0, td; td = tds[i]; i++) { + td.onmouseover = td.onclick = null; + }; + + var butts = o.table.getElementsByTagName("span"); + for(var i = 0, butt; butt = butts[i]; i++) { + butt.onmousedown = butt.onclick = butt.onkeypress = null; + }; + + o.ths = o.trs = null; + + clearTimeout(o.fadeTimer); + clearTimeout(o.timer); + o.fadeTimer = o.timer = null; + + /*@cc_on + @if(@_jscript_version <= 5.6) + o.iePopUp = null; + @end + @*/ + + if(!o.staticPos && document.getElementById(o.id.replace(/^fd-/, 'fd-but-'))) { + var butt = document.getElementById(o.id.replace(/^fd-/, 'fd-but-')); + butt.onclick = butt.onpress = null; + }; + + if(o.div && o.div.parentNode) { + o.div.parentNode.removeChild(o.div); + }; + + o.titleBar = o.table = o.div = null; + o = null; + }; + o.create(); +}; + +datePickerController = function() { + var datePickers = {}; + var uniqueId = 0; + + var addEvent = function(obj, type, fn) { + if( obj.attachEvent ) { + obj["e"+type+fn] = fn; + obj[type+fn] = function(){obj["e"+type+fn]( window.event );}; + obj.attachEvent( "on"+type, obj[type+fn] ); + } else { + obj.addEventListener( type, fn, true ); + }; + }; + var removeEvent = function(obj, type, fn) { + try { + if( obj.detachEvent ) { + obj.detachEvent( "on"+type, obj[type+fn] ); + obj[type+fn] = null; + } else { + obj.removeEventListener( type, fn, true ); + }; + } catch(err) {}; + }; + var hideAll = function(exception) { + var dp; + for(dp in datePickers) { + if(!datePickers[dp].created || datePickers[dp].staticPos) continue; + if(exception && exception == datePickers[dp].id) { continue; }; + if(document.getElementById(datePickers[dp].id)) { datePickers[dp].hide(); }; + }; + }; + var cleanUp = function() { + var dp; + for(dp in datePickers) { + if(!document.getElementById(datePickers[dp].id)) { + if(!datePickers[dp].created) continue; + datePickers[dp].destroy(); + datePickers[dp] = null; + delete datePickers[dp]; + }; + }; + }; + var destroy = function() { + for(dp in datePickers) { + if(!datePickers[dp].created) continue; + datePickers[dp].destroy(); + datePickers[dp] = null; + delete datePickers[dp]; + }; + datePickers = null; + /*@cc_on + @if(@_jscript_version <= 5.6) + if(document.getElementById("iePopUpHack")) { + document.body.removeChild(document.getElementById("iePopUpHack")); + }; + @end + @*/ + datePicker.script = null; + removeEvent(window, 'load', datePickerController.create); + removeEvent(window, 'unload', datePickerController.destroy); + }; + var dateFormat = function(dateIn, favourMDY) { + var dateTest = [ + { regExp:/^(0?[1-9]|[12][0-9]|3[01])([- \/.])(0?[1-9]|1[012])([- \/.])((\d\d)?\d\d)$/, d:1, m:3, y:5 }, // dmy + { regExp:/^(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])([- \/.])((\d\d)?\d\d)$/, d:3, m:1, y:5 }, // mdy + { regExp:/^(\d\d\d\d)([- \/.])(0?[1-9]|1[012])([- \/.])(0?[1-9]|[12][0-9]|3[01])$/, d:5, m:3, y:1 } // ymd + ]; + + var start; + var cnt = 0; + while(cnt < 3) { + start = (cnt + (favourMDY ? 4 : 3)) % 3; + if(dateIn.match(dateTest[start].regExp)) { + res = dateIn.match(dateTest[start].regExp); + y = res[dateTest[start].y]; + m = res[dateTest[start].m]; + d = res[dateTest[start].d]; + if(m.length == 1) m = "0" + m; + if(d.length == 1) d = "0" + d; + if(y.length != 4) y = (parseInt(y) < 50) ? '20' + y : '19' + y; + return String(y)+m+d; + }; + cnt++; + }; + return 0; + }; + var joinNodeLists = function() { + if(!arguments.length) { return []; } + var nodeList = []; + for (var i = 0; i < arguments.length; i++) { + for (var j = 0, item; item = arguments[i][j]; j++) { + nodeList[nodeList.length] = item; + }; + }; + return nodeList; + }; + var addDatePicker = function(inpId, options) { + if(!(inpId in datePickers)) { + datePickers[inpId] = new datePicker(options); + }; + }; + var getDatePicker = function(inpId) { + if(!(inpId in datePickers)) { throw "No datePicker has been created for the form element with an id of '" + inpId.toString() + "'"; }; + return datePickers[inpId]; + }; + var grepRangeLimits = function(sel) { + var range = []; + for(var i = 0; i < sel.options.length; i++) { + if(sel.options[i].value.search(/^\d\d\d\d$/) == -1) { continue; }; + if(!range[0] || Number(sel.options[i].value) < range[0]) { range[0] = Number(sel.options[i].value); }; + if(!range[1] || Number(sel.options[i].value) > range[1]) { range[1] = Number(sel.options[i].value); }; + }; + return range; + }; + var create = function(inp) { + if(!(typeof document.createElement != "undefined" && typeof document.documentElement != "undefined" && typeof document.documentElement.offsetWidth == "number")) return; + + var inputs = (inp && inp.tagName) ? [inp] : joinNodeLists(document.getElementsByTagName('input'), document.getElementsByTagName('select')); + var regExp1 = /disable-days-([1-7]){1,6}/g; // the days to disable + var regExp2 = /no-transparency/g; // do not use transparency effects + var regExp3 = /highlight-days-([1-7]){1,7}/g; // the days to highlight in red + var regExp4 = /range-low-(\d\d\d\d-\d\d-\d\d)/g; // the lowest selectable date + var regExp5 = /range-high-(\d\d\d\d-\d\d-\d\d)/g; // the highest selectable date + var regExp6 = /format-(d-m-y|m-d-y|y-m-d)/g; // the input/output date format + var regExp7 = /divider-(dot|slash|space|dash)/g; // the character used to divide the date + var regExp8 = /no-locale/g; // do not attempt to detect the browser language + var regExp9 = /no-fade/g; // always show the datepicker + var regExp10 = /hide-input/g; // hide the input + + for(var i=0, inp; inp = inputs[i]; i++) { + if(inp.className && (inp.className.search(regExp6) != -1 || inp.className.search(/split-date/) != -1) && ((inp.tagName.toLowerCase() == "input" && (inp.type == "text" || inp.type == "hidden")) || inp.tagName.toLowerCase() == "select")) { + + if(inp.id && document.getElementById('fd-'+inp.id)) { continue; }; + + if(!inp.id) { inp.id = "fdDatePicker-" + uniqueId++; }; + + var options = { + id:inp.id, + low:"", + high:"", + divider:"/", + format:"d-m-y", + highlightDays:[0,0,0,0,0,1,1], + disableDays:[0,0,0,0,0,0,0], + locale:inp.className.search(regExp8) == -1, + splitDate:0, + noTransparency:inp.className.search(regExp2) != -1, + staticPos:inp.className.search(regExp9) != -1, + hideInput:inp.className.search(regExp10) != -1 + }; + + if(!options.staticPos) { + options.hideInput = false; + } else { + options.noTransparency = true; + }; + + // Split the date into three parts ? + if(inp.className.search(/split-date/) != -1) { + if(document.getElementById(inp.id+'-dd') && document.getElementById(inp.id+'-mm') && document.getElementById(inp.id+'-dd').tagName.search(/input|select/i) != -1 && document.getElementById(inp.id+'-mm').tagName.search(/input|select/i) != -1) { + options.splitDate = 1; + }; + }; + + // Date format(variations of d-m-y) + if(inp.className.search(regExp6) != -1) { + options.format = inp.className.match(regExp6)[0].replace('format-',''); + }; + + // What divider to use, a "/", "-", "." or " " + if(inp.className.search(regExp7) != -1) { + var dividers = { dot:".", space:" ", dash:"-", slash:"/" }; + options.divider = (inp.className.search(regExp7) != -1 && inp.className.match(regExp7)[0].replace('divider-','') in dividers) ? dividers[inp.className.match(regExp7)[0].replace('divider-','')] : "/"; + }; + + // The days to highlight + if(inp.className.search(regExp3) != -1) { + var tmp = inp.className.match(regExp3)[0].replace(/highlight-days-/, ''); + options.highlightDays = [0,0,0,0,0,0,0]; + for(var j = 0; j < tmp.length; j++) { + options.highlightDays[tmp.charAt(j) - 1] = 1; + }; + }; + + // The days to disable + if(inp.className.search(regExp1) != -1) { + var tmp = inp.className.match(regExp1)[0].replace(/disable-days-/, ''); + options.disableDays = [0,0,0,0,0,0,0]; + for(var j = 0; j < tmp.length; j++) { + options.disableDays[tmp.charAt(j) - 1] = 1; + }; + }; + + // The lower limit + if(inp.className.search(/range-low-today/i) != -1) { + options.low = datePickerController.dateFormat((new Date().getMonth() + 1) + "/" + new Date().getDate() + "/" + new Date().getFullYear(), true); + } else if(inp.className.search(regExp4) != -1) { + options.low = datePickerController.dateFormat(inp.className.match(regExp4)[0].replace(/range-low-/, ''), false); + if(!options.low) { + options.low = ''; + }; + }; + + // The higher limit + if(inp.className.search(/range-high-today/i) != -1 && inp.className.search(/range-low-today/i) == -1) { + options.high = datePickerController.dateFormat((new Date().getMonth() + 1) + "/" + new Date().getDate() + "/" + new Date().getFullYear(), true); + } else if(inp.className.search(regExp5) != -1) { + options.high = datePickerController.dateFormat(inp.className.match(regExp5)[0].replace(/range-high-/, ''), false); + if(!options.high) { + options.high = ''; + }; + }; + + // Always round lower & higher limits if a selectList involved + if(inp.tagName.search(/select/i) != -1) { + var range = grepRangeLimits(inp); + options.low = options.low ? range[0] + String(options.low).substr(4,4) : datePickerController.dateFormat(range[0] + "/01/01"); + options.high = options.high ? range[1] + String(options.low).substr(4,4) : datePickerController.dateFormat(range[1] + "/12/31"); + }; + + addDatePicker(inp.id, options); + }; + }; + } + + return { + addEvent:addEvent, + removeEvent:removeEvent, + create:create, + destroy:destroy, + cleanUp:cleanUp, + addDatePicker:addDatePicker, + getDatePicker:getDatePicker, + dateFormat:dateFormat, + datePickers:datePickers, + hideAll:hideAll + }; +}(); + +})(); + +datePickerController.addEvent(window, 'load', datePickerController.create); +datePickerController.addEvent(window, 'unload', datePickerController.destroy); diff --git a/spec/test_app/public/javascripts/gateway.js b/spec/test_app/public/javascripts/gateway.js new file mode 100644 index 0000000..f8dc477 --- /dev/null +++ b/spec/test_app/public/javascripts/gateway.js @@ -0,0 +1,13 @@ +$j(function() { + var original_gtwy_type = $j('#gtwy-type').attr('value'); + $j('div#gateway-settings-warning').hide(); + $j('#gtwy-type').change(function() { + if ($j('#gtwy-type').attr('value') == original_gtwy_type) { + $j('div.gateway-settings').show(); + $j('div#gateway-settings-warning').hide(); + } else { + $j('div.gateway-settings').hide(); + $j('div#gateway-settings-warning').show(); + } + }); +}) \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery-1.4.2.min.js b/spec/test_app/public/javascripts/jquery-1.4.2.min.js new file mode 100644 index 0000000..7c24308 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery-1.4.2.min.js @@ -0,0 +1,154 @@ +/*! + * jQuery JavaScript Library v1.4.2 + * http://jquery.com/ + * + * Copyright 2010, John Resig + * Dual licensed under the MIT or GPL Version 2 licenses. + * http://jquery.org/license + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * Copyright 2010, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * + * Date: Sat Feb 13 22:33:48 2010 -0500 + */ +(function(A,w){function ma(){if(!c.isReady){try{s.documentElement.doScroll("left")}catch(a){setTimeout(ma,1);return}c.ready()}}function Qa(a,b){b.src?c.ajax({url:b.src,async:false,dataType:"script"}):c.globalEval(b.text||b.textContent||b.innerHTML||"");b.parentNode&&b.parentNode.removeChild(b)}function X(a,b,d,f,e,j){var i=a.length;if(typeof b==="object"){for(var o in b)X(a,o,b[o],f,e,d);return a}if(d!==w){f=!j&&f&&c.isFunction(d);for(o=0;o)[^>]*$|^#([\w-]+)$/,Ua=/^.[^:#\[\.,]*$/,Va=/\S/, +Wa=/^(\s|\u00A0)+|(\s|\u00A0)+$/g,Xa=/^<(\w+)\s*\/?>(?:<\/\1>)?$/,P=navigator.userAgent,xa=false,Q=[],L,$=Object.prototype.toString,aa=Object.prototype.hasOwnProperty,ba=Array.prototype.push,R=Array.prototype.slice,ya=Array.prototype.indexOf;c.fn=c.prototype={init:function(a,b){var d,f;if(!a)return this;if(a.nodeType){this.context=this[0]=a;this.length=1;return this}if(a==="body"&&!b){this.context=s;this[0]=s.body;this.selector="body";this.length=1;return this}if(typeof a==="string")if((d=Ta.exec(a))&& +(d[1]||!b))if(d[1]){f=b?b.ownerDocument||b:s;if(a=Xa.exec(a))if(c.isPlainObject(b)){a=[s.createElement(a[1])];c.fn.attr.call(a,b,true)}else a=[f.createElement(a[1])];else{a=sa([d[1]],[f]);a=(a.cacheable?a.fragment.cloneNode(true):a.fragment).childNodes}return c.merge(this,a)}else{if(b=s.getElementById(d[2])){if(b.id!==d[2])return T.find(a);this.length=1;this[0]=b}this.context=s;this.selector=a;return this}else if(!b&&/^\w+$/.test(a)){this.selector=a;this.context=s;a=s.getElementsByTagName(a);return c.merge(this, +a)}else return!b||b.jquery?(b||T).find(a):c(b).find(a);else if(c.isFunction(a))return T.ready(a);if(a.selector!==w){this.selector=a.selector;this.context=a.context}return c.makeArray(a,this)},selector:"",jquery:"1.4.2",length:0,size:function(){return this.length},toArray:function(){return R.call(this,0)},get:function(a){return a==null?this.toArray():a<0?this.slice(a)[0]:this[a]},pushStack:function(a,b,d){var f=c();c.isArray(a)?ba.apply(f,a):c.merge(f,a);f.prevObject=this;f.context=this.context;if(b=== +"find")f.selector=this.selector+(this.selector?" ":"")+d;else if(b)f.selector=this.selector+"."+b+"("+d+")";return f},each:function(a,b){return c.each(this,a,b)},ready:function(a){c.bindReady();if(c.isReady)a.call(s,c);else Q&&Q.push(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(R.apply(this,arguments),"slice",R.call(arguments).join(","))},map:function(a){return this.pushStack(c.map(this, +function(b,d){return a.call(b,d,b)}))},end:function(){return this.prevObject||c(null)},push:ba,sort:[].sort,splice:[].splice};c.fn.init.prototype=c.fn;c.extend=c.fn.extend=function(){var a=arguments[0]||{},b=1,d=arguments.length,f=false,e,j,i,o;if(typeof a==="boolean"){f=a;a=arguments[1]||{};b=2}if(typeof a!=="object"&&!c.isFunction(a))a={};if(d===b){a=this;--b}for(;b
<%= t("category") %> - <%= t("questions") %> -  <%= t("category") %> + <%= t("questions") %> + <% end %> + + <%= hook :admin_question_categories_header_actions %> +
<%= h category.name %><%= category.questions.count %>
<%= h category.name %><%= category.questions.count %> - <%= link_to_edit category.id %>  - <%= link_to_delete category.id %> + <%= hook :admin_question_categories_index_row_actions, locals do %> + <%= link_to_edit category %>  + <%= link_to_delete category %> + <% end %>
a"; +var e=d.getElementsByTagName("*"),j=d.getElementsByTagName("a")[0];if(!(!e||!e.length||!j)){c.support={leadingWhitespace:d.firstChild.nodeType===3,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/red/.test(j.getAttribute("style")),hrefNormalized:j.getAttribute("href")==="/a",opacity:/^0.55$/.test(j.style.opacity),cssFloat:!!j.style.cssFloat,checkOn:d.getElementsByTagName("input")[0].value==="on",optSelected:s.createElement("select").appendChild(s.createElement("option")).selected, +parentNode:d.removeChild(d.appendChild(s.createElement("div"))).parentNode===null,deleteExpando:true,checkClone:false,scriptEval:false,noCloneEvent:true,boxModel:null};b.type="text/javascript";try{b.appendChild(s.createTextNode("window."+f+"=1;"))}catch(i){}a.insertBefore(b,a.firstChild);if(A[f]){c.support.scriptEval=true;delete A[f]}try{delete b.test}catch(o){c.support.deleteExpando=false}a.removeChild(b);if(d.attachEvent&&d.fireEvent){d.attachEvent("onclick",function k(){c.support.noCloneEvent= +false;d.detachEvent("onclick",k)});d.cloneNode(true).fireEvent("onclick")}d=s.createElement("div");d.innerHTML="";a=s.createDocumentFragment();a.appendChild(d.firstChild);c.support.checkClone=a.cloneNode(true).cloneNode(true).lastChild.checked;c(function(){var k=s.createElement("div");k.style.width=k.style.paddingLeft="1px";s.body.appendChild(k);c.boxModel=c.support.boxModel=k.offsetWidth===2;s.body.removeChild(k).style.display="none"});a=function(k){var n= +s.createElement("div");k="on"+k;var r=k in n;if(!r){n.setAttribute(k,"return;");r=typeof n[k]==="function"}return r};c.support.submitBubbles=a("submit");c.support.changeBubbles=a("change");a=b=d=e=j=null}})();c.props={"for":"htmlFor","class":"className",readonly:"readOnly",maxlength:"maxLength",cellspacing:"cellSpacing",rowspan:"rowSpan",colspan:"colSpan",tabindex:"tabIndex",usemap:"useMap",frameborder:"frameBorder"};var G="jQuery"+J(),Ya=0,za={};c.extend({cache:{},expando:G,noData:{embed:true,object:true, +applet:true},data:function(a,b,d){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var f=a[G],e=c.cache;if(!f&&typeof b==="string"&&d===w)return null;f||(f=++Ya);if(typeof b==="object"){a[G]=f;e[f]=c.extend(true,{},b)}else if(!e[f]){a[G]=f;e[f]={}}a=e[f];if(d!==w)a[b]=d;return typeof b==="string"?a[b]:a}},removeData:function(a,b){if(!(a.nodeName&&c.noData[a.nodeName.toLowerCase()])){a=a==A?za:a;var d=a[G],f=c.cache,e=f[d];if(b){if(e){delete e[b];c.isEmptyObject(e)&&c.removeData(a)}}else{if(c.support.deleteExpando)delete a[c.expando]; +else a.removeAttribute&&a.removeAttribute(c.expando);delete f[d]}}}});c.fn.extend({data:function(a,b){if(typeof a==="undefined"&&this.length)return c.data(this[0]);else if(typeof a==="object")return this.each(function(){c.data(this,a)});var d=a.split(".");d[1]=d[1]?"."+d[1]:"";if(b===w){var f=this.triggerHandler("getData"+d[1]+"!",[d[0]]);if(f===w&&this.length)f=c.data(this[0],a);return f===w&&d[1]?this.data(d[0]):f}else return this.trigger("setData"+d[1]+"!",[d[0],b]).each(function(){c.data(this, +a,b)})},removeData:function(a){return this.each(function(){c.removeData(this,a)})}});c.extend({queue:function(a,b,d){if(a){b=(b||"fx")+"queue";var f=c.data(a,b);if(!d)return f||[];if(!f||c.isArray(d))f=c.data(a,b,c.makeArray(d));else f.push(d);return f}},dequeue:function(a,b){b=b||"fx";var d=c.queue(a,b),f=d.shift();if(f==="inprogress")f=d.shift();if(f){b==="fx"&&d.unshift("inprogress");f.call(a,function(){c.dequeue(a,b)})}}});c.fn.extend({queue:function(a,b){if(typeof a!=="string"){b=a;a="fx"}if(b=== +w)return c.queue(this[0],a);return this.each(function(){var d=c.queue(this,a,b);a==="fx"&&d[0]!=="inprogress"&&c.dequeue(this,a)})},dequeue:function(a){return this.each(function(){c.dequeue(this,a)})},delay:function(a,b){a=c.fx?c.fx.speeds[a]||a:a;b=b||"fx";return this.queue(b,function(){var d=this;setTimeout(function(){c.dequeue(d,b)},a)})},clearQueue:function(a){return this.queue(a||"fx",[])}});var Aa=/[\n\t]/g,ca=/\s+/,Za=/\r/g,$a=/href|src|style/,ab=/(button|input)/i,bb=/(button|input|object|select|textarea)/i, +cb=/^(a|area)$/i,Ba=/radio|checkbox/;c.fn.extend({attr:function(a,b){return X(this,a,b,true,c.attr)},removeAttr:function(a){return this.each(function(){c.attr(this,a,"");this.nodeType===1&&this.removeAttribute(a)})},addClass:function(a){if(c.isFunction(a))return this.each(function(n){var r=c(this);r.addClass(a.call(this,n,r.attr("class")))});if(a&&typeof a==="string")for(var b=(a||"").split(ca),d=0,f=this.length;d-1)return true;return false},val:function(a){if(a===w){var b=this[0];if(b){if(c.nodeName(b,"option"))return(b.attributes.value||{}).specified?b.value:b.text;if(c.nodeName(b,"select")){var d=b.selectedIndex,f=[],e=b.options;b=b.type==="select-one";if(d<0)return null;var j=b?d:0;for(d=b?d+1:e.length;j=0;else if(c.nodeName(this,"select")){var u=c.makeArray(r);c("option",this).each(function(){this.selected= +c.inArray(c(this).val(),u)>=0});if(!u.length)this.selectedIndex=-1}else this.value=r}})}});c.extend({attrFn:{val:true,css:true,html:true,text:true,data:true,width:true,height:true,offset:true},attr:function(a,b,d,f){if(!a||a.nodeType===3||a.nodeType===8)return w;if(f&&b in c.attrFn)return c(a)[b](d);f=a.nodeType!==1||!c.isXMLDoc(a);var e=d!==w;b=f&&c.props[b]||b;if(a.nodeType===1){var j=$a.test(b);if(b in a&&f&&!j){if(e){b==="type"&&ab.test(a.nodeName)&&a.parentNode&&c.error("type property can't be changed"); +a[b]=d}if(c.nodeName(a,"form")&&a.getAttributeNode(b))return a.getAttributeNode(b).nodeValue;if(b==="tabIndex")return(b=a.getAttributeNode("tabIndex"))&&b.specified?b.value:bb.test(a.nodeName)||cb.test(a.nodeName)&&a.href?0:w;return a[b]}if(!c.support.style&&f&&b==="style"){if(e)a.style.cssText=""+d;return a.style.cssText}e&&a.setAttribute(b,""+d);a=!c.support.hrefNormalized&&f&&j?a.getAttribute(b,2):a.getAttribute(b);return a===null?w:a}return c.style(a,b,d)}});var O=/\.(.*)$/,db=function(a){return a.replace(/[^\w\s\.\|`]/g, +function(b){return"\\"+b})};c.event={add:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){if(a.setInterval&&a!==A&&!a.frameElement)a=A;var e,j;if(d.handler){e=d;d=e.handler}if(!d.guid)d.guid=c.guid++;if(j=c.data(a)){var i=j.events=j.events||{},o=j.handle;if(!o)j.handle=o=function(){return typeof c!=="undefined"&&!c.event.triggered?c.event.handle.apply(o.elem,arguments):w};o.elem=a;b=b.split(" ");for(var k,n=0,r;k=b[n++];){j=e?c.extend({},e):{handler:d,data:f};if(k.indexOf(".")>-1){r=k.split("."); +k=r.shift();j.namespace=r.slice(0).sort().join(".")}else{r=[];j.namespace=""}j.type=k;j.guid=d.guid;var u=i[k],z=c.event.special[k]||{};if(!u){u=i[k]=[];if(!z.setup||z.setup.call(a,f,r,o)===false)if(a.addEventListener)a.addEventListener(k,o,false);else a.attachEvent&&a.attachEvent("on"+k,o)}if(z.add){z.add.call(a,j);if(!j.handler.guid)j.handler.guid=d.guid}u.push(j);c.event.global[k]=true}a=null}}},global:{},remove:function(a,b,d,f){if(!(a.nodeType===3||a.nodeType===8)){var e,j=0,i,o,k,n,r,u,z=c.data(a), +C=z&&z.events;if(z&&C){if(b&&b.type){d=b.handler;b=b.type}if(!b||typeof b==="string"&&b.charAt(0)==="."){b=b||"";for(e in C)c.event.remove(a,e+b)}else{for(b=b.split(" ");e=b[j++];){n=e;i=e.indexOf(".")<0;o=[];if(!i){o=e.split(".");e=o.shift();k=new RegExp("(^|\\.)"+c.map(o.slice(0).sort(),db).join("\\.(?:.*\\.)?")+"(\\.|$)")}if(r=C[e])if(d){n=c.event.special[e]||{};for(B=f||0;B=0){a.type= +e=e.slice(0,-1);a.exclusive=true}if(!d){a.stopPropagation();c.event.global[e]&&c.each(c.cache,function(){this.events&&this.events[e]&&c.event.trigger(a,b,this.handle.elem)})}if(!d||d.nodeType===3||d.nodeType===8)return w;a.result=w;a.target=d;b=c.makeArray(b);b.unshift(a)}a.currentTarget=d;(f=c.data(d,"handle"))&&f.apply(d,b);f=d.parentNode||d.ownerDocument;try{if(!(d&&d.nodeName&&c.noData[d.nodeName.toLowerCase()]))if(d["on"+e]&&d["on"+e].apply(d,b)===false)a.result=false}catch(j){}if(!a.isPropagationStopped()&& +f)c.event.trigger(a,b,f,true);else if(!a.isDefaultPrevented()){f=a.target;var i,o=c.nodeName(f,"a")&&e==="click",k=c.event.special[e]||{};if((!k._default||k._default.call(d,a)===false)&&!o&&!(f&&f.nodeName&&c.noData[f.nodeName.toLowerCase()])){try{if(f[e]){if(i=f["on"+e])f["on"+e]=null;c.event.triggered=true;f[e]()}}catch(n){}if(i)f["on"+e]=i;c.event.triggered=false}}},handle:function(a){var b,d,f,e;a=arguments[0]=c.event.fix(a||A.event);a.currentTarget=this;b=a.type.indexOf(".")<0&&!a.exclusive; +if(!b){d=a.type.split(".");a.type=d.shift();f=new RegExp("(^|\\.)"+d.slice(0).sort().join("\\.(?:.*\\.)?")+"(\\.|$)")}e=c.data(this,"events");d=e[a.type];if(e&&d){d=d.slice(0);e=0;for(var j=d.length;e-1?c.map(a.options,function(f){return f.selected}).join("-"):"";else if(a.nodeName.toLowerCase()==="select")d=a.selectedIndex;return d},fa=function(a,b){var d=a.target,f,e;if(!(!da.test(d.nodeName)||d.readOnly)){f=c.data(d,"_change_data");e=Fa(d);if(a.type!=="focusout"||d.type!=="radio")c.data(d,"_change_data", +e);if(!(f===w||e===f))if(f!=null||e){a.type="change";return c.event.trigger(a,b,d)}}};c.event.special.change={filters:{focusout:fa,click:function(a){var b=a.target,d=b.type;if(d==="radio"||d==="checkbox"||b.nodeName.toLowerCase()==="select")return fa.call(this,a)},keydown:function(a){var b=a.target,d=b.type;if(a.keyCode===13&&b.nodeName.toLowerCase()!=="textarea"||a.keyCode===32&&(d==="checkbox"||d==="radio")||d==="select-multiple")return fa.call(this,a)},beforeactivate:function(a){a=a.target;c.data(a, +"_change_data",Fa(a))}},setup:function(){if(this.type==="file")return false;for(var a in ea)c.event.add(this,a+".specialChange",ea[a]);return da.test(this.nodeName)},teardown:function(){c.event.remove(this,".specialChange");return da.test(this.nodeName)}};ea=c.event.special.change.filters}s.addEventListener&&c.each({focus:"focusin",blur:"focusout"},function(a,b){function d(f){f=c.event.fix(f);f.type=b;return c.event.handle.call(this,f)}c.event.special[b]={setup:function(){this.addEventListener(a, +d,true)},teardown:function(){this.removeEventListener(a,d,true)}}});c.each(["bind","one"],function(a,b){c.fn[b]=function(d,f,e){if(typeof d==="object"){for(var j in d)this[b](j,f,d[j],e);return this}if(c.isFunction(f)){e=f;f=w}var i=b==="one"?c.proxy(e,function(k){c(this).unbind(k,i);return e.apply(this,arguments)}):e;if(d==="unload"&&b!=="one")this.one(d,f,e);else{j=0;for(var o=this.length;j0){y=t;break}}t=t[g]}m[q]=y}}}var f=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g, +e=0,j=Object.prototype.toString,i=false,o=true;[0,0].sort(function(){o=false;return 0});var k=function(g,h,l,m){l=l||[];var q=h=h||s;if(h.nodeType!==1&&h.nodeType!==9)return[];if(!g||typeof g!=="string")return l;for(var p=[],v,t,y,S,H=true,M=x(h),I=g;(f.exec(""),v=f.exec(I))!==null;){I=v[3];p.push(v[1]);if(v[2]){S=v[3];break}}if(p.length>1&&r.exec(g))if(p.length===2&&n.relative[p[0]])t=ga(p[0]+p[1],h);else for(t=n.relative[p[0]]?[h]:k(p.shift(),h);p.length;){g=p.shift();if(n.relative[g])g+=p.shift(); +t=ga(g,t)}else{if(!m&&p.length>1&&h.nodeType===9&&!M&&n.match.ID.test(p[0])&&!n.match.ID.test(p[p.length-1])){v=k.find(p.shift(),h,M);h=v.expr?k.filter(v.expr,v.set)[0]:v.set[0]}if(h){v=m?{expr:p.pop(),set:z(m)}:k.find(p.pop(),p.length===1&&(p[0]==="~"||p[0]==="+")&&h.parentNode?h.parentNode:h,M);t=v.expr?k.filter(v.expr,v.set):v.set;if(p.length>0)y=z(t);else H=false;for(;p.length;){var D=p.pop();v=D;if(n.relative[D])v=p.pop();else D="";if(v==null)v=h;n.relative[D](y,v,M)}}else y=[]}y||(y=t);y||k.error(D|| +g);if(j.call(y)==="[object Array]")if(H)if(h&&h.nodeType===1)for(g=0;y[g]!=null;g++){if(y[g]&&(y[g]===true||y[g].nodeType===1&&E(h,y[g])))l.push(t[g])}else for(g=0;y[g]!=null;g++)y[g]&&y[g].nodeType===1&&l.push(t[g]);else l.push.apply(l,y);else z(y,l);if(S){k(S,q,l,m);k.uniqueSort(l)}return l};k.uniqueSort=function(g){if(B){i=o;g.sort(B);if(i)for(var h=1;h":function(g,h){var l=typeof h==="string";if(l&&!/\W/.test(h)){h=h.toLowerCase();for(var m=0,q=g.length;m=0))l||m.push(v);else if(l)h[p]=false;return false},ID:function(g){return g[1].replace(/\\/g,"")},TAG:function(g){return g[1].toLowerCase()}, +CHILD:function(g){if(g[1]==="nth"){var h=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(g[2]==="even"&&"2n"||g[2]==="odd"&&"2n+1"||!/\D/.test(g[2])&&"0n+"+g[2]||g[2]);g[2]=h[1]+(h[2]||1)-0;g[3]=h[3]-0}g[0]=e++;return g},ATTR:function(g,h,l,m,q,p){h=g[1].replace(/\\/g,"");if(!p&&n.attrMap[h])g[1]=n.attrMap[h];if(g[2]==="~=")g[4]=" "+g[4]+" ";return g},PSEUDO:function(g,h,l,m,q){if(g[1]==="not")if((f.exec(g[3])||"").length>1||/^\w/.test(g[3]))g[3]=k(g[3],null,null,h);else{g=k.filter(g[3],h,l,true^q);l||m.push.apply(m, +g);return false}else if(n.match.POS.test(g[0])||n.match.CHILD.test(g[0]))return true;return g},POS:function(g){g.unshift(true);return g}},filters:{enabled:function(g){return g.disabled===false&&g.type!=="hidden"},disabled:function(g){return g.disabled===true},checked:function(g){return g.checked===true},selected:function(g){return g.selected===true},parent:function(g){return!!g.firstChild},empty:function(g){return!g.firstChild},has:function(g,h,l){return!!k(l[3],g).length},header:function(g){return/h\d/i.test(g.nodeName)}, +text:function(g){return"text"===g.type},radio:function(g){return"radio"===g.type},checkbox:function(g){return"checkbox"===g.type},file:function(g){return"file"===g.type},password:function(g){return"password"===g.type},submit:function(g){return"submit"===g.type},image:function(g){return"image"===g.type},reset:function(g){return"reset"===g.type},button:function(g){return"button"===g.type||g.nodeName.toLowerCase()==="button"},input:function(g){return/input|select|textarea|button/i.test(g.nodeName)}}, +setFilters:{first:function(g,h){return h===0},last:function(g,h,l,m){return h===m.length-1},even:function(g,h){return h%2===0},odd:function(g,h){return h%2===1},lt:function(g,h,l){return hl[3]-0},nth:function(g,h,l){return l[3]-0===h},eq:function(g,h,l){return l[3]-0===h}},filter:{PSEUDO:function(g,h,l,m){var q=h[1],p=n.filters[q];if(p)return p(g,l,h,m);else if(q==="contains")return(g.textContent||g.innerText||a([g])||"").indexOf(h[3])>=0;else if(q==="not"){h= +h[3];l=0;for(m=h.length;l=0}},ID:function(g,h){return g.nodeType===1&&g.getAttribute("id")===h},TAG:function(g,h){return h==="*"&&g.nodeType===1||g.nodeName.toLowerCase()===h},CLASS:function(g,h){return(" "+(g.className||g.getAttribute("class"))+" ").indexOf(h)>-1},ATTR:function(g,h){var l=h[1];g=n.attrHandle[l]?n.attrHandle[l](g):g[l]!=null?g[l]:g.getAttribute(l);l=g+"";var m=h[2];h=h[4];return g==null?m==="!=":m=== +"="?l===h:m==="*="?l.indexOf(h)>=0:m==="~="?(" "+l+" ").indexOf(h)>=0:!h?l&&g!==false:m==="!="?l!==h:m==="^="?l.indexOf(h)===0:m==="$="?l.substr(l.length-h.length)===h:m==="|="?l===h||l.substr(0,h.length+1)===h+"-":false},POS:function(g,h,l,m){var q=n.setFilters[h[2]];if(q)return q(g,l,h,m)}}},r=n.match.POS;for(var u in n.match){n.match[u]=new RegExp(n.match[u].source+/(?![^\[]*\])(?![^\(]*\))/.source);n.leftMatch[u]=new RegExp(/(^(?:.|\r|\n)*?)/.source+n.match[u].source.replace(/\\(\d+)/g,function(g, +h){return"\\"+(h-0+1)}))}var z=function(g,h){g=Array.prototype.slice.call(g,0);if(h){h.push.apply(h,g);return h}return g};try{Array.prototype.slice.call(s.documentElement.childNodes,0)}catch(C){z=function(g,h){h=h||[];if(j.call(g)==="[object Array]")Array.prototype.push.apply(h,g);else if(typeof g.length==="number")for(var l=0,m=g.length;l";var l=s.documentElement;l.insertBefore(g,l.firstChild);if(s.getElementById(h)){n.find.ID=function(m,q,p){if(typeof q.getElementById!=="undefined"&&!p)return(q=q.getElementById(m[1]))?q.id===m[1]||typeof q.getAttributeNode!=="undefined"&& +q.getAttributeNode("id").nodeValue===m[1]?[q]:w:[]};n.filter.ID=function(m,q){var p=typeof m.getAttributeNode!=="undefined"&&m.getAttributeNode("id");return m.nodeType===1&&p&&p.nodeValue===q}}l.removeChild(g);l=g=null})();(function(){var g=s.createElement("div");g.appendChild(s.createComment(""));if(g.getElementsByTagName("*").length>0)n.find.TAG=function(h,l){l=l.getElementsByTagName(h[1]);if(h[1]==="*"){h=[];for(var m=0;l[m];m++)l[m].nodeType===1&&h.push(l[m]);l=h}return l};g.innerHTML=""; +if(g.firstChild&&typeof g.firstChild.getAttribute!=="undefined"&&g.firstChild.getAttribute("href")!=="#")n.attrHandle.href=function(h){return h.getAttribute("href",2)};g=null})();s.querySelectorAll&&function(){var g=k,h=s.createElement("div");h.innerHTML="

";if(!(h.querySelectorAll&&h.querySelectorAll(".TEST").length===0)){k=function(m,q,p,v){q=q||s;if(!v&&q.nodeType===9&&!x(q))try{return z(q.querySelectorAll(m),p)}catch(t){}return g(m,q,p,v)};for(var l in g)k[l]=g[l];h=null}}(); +(function(){var g=s.createElement("div");g.innerHTML="
";if(!(!g.getElementsByClassName||g.getElementsByClassName("e").length===0)){g.lastChild.className="e";if(g.getElementsByClassName("e").length!==1){n.order.splice(1,0,"CLASS");n.find.CLASS=function(h,l,m){if(typeof l.getElementsByClassName!=="undefined"&&!m)return l.getElementsByClassName(h[1])};g=null}}})();var E=s.compareDocumentPosition?function(g,h){return!!(g.compareDocumentPosition(h)&16)}: +function(g,h){return g!==h&&(g.contains?g.contains(h):true)},x=function(g){return(g=(g?g.ownerDocument||g:0).documentElement)?g.nodeName!=="HTML":false},ga=function(g,h){var l=[],m="",q;for(h=h.nodeType?[h]:h;q=n.match.PSEUDO.exec(g);){m+=q[0];g=g.replace(n.match.PSEUDO,"")}g=n.relative[g]?g+"*":g;q=0;for(var p=h.length;q=0===d})};c.fn.extend({find:function(a){for(var b=this.pushStack("","find",a),d=0,f=0,e=this.length;f0)for(var j=d;j0},closest:function(a,b){if(c.isArray(a)){var d=[],f=this[0],e,j= +{},i;if(f&&a.length){e=0;for(var o=a.length;e-1:c(f).is(e)){d.push({selector:i,elem:f});delete j[i]}}f=f.parentNode}}return d}var k=c.expr.match.POS.test(a)?c(a,b||this.context):null;return this.map(function(n,r){for(;r&&r.ownerDocument&&r!==b;){if(k?k.index(r)>-1:c(r).is(a))return r;r=r.parentNode}return null})},index:function(a){if(!a||typeof a=== +"string")return c.inArray(this[0],a?c(a):this.parent().children());return c.inArray(a.jquery?a[0]:a,this)},add:function(a,b){a=typeof a==="string"?c(a,b||this.context):c.makeArray(a);b=c.merge(this.get(),a);return this.pushStack(qa(a[0])||qa(b[0])?b:c.unique(b))},andSelf:function(){return this.add(this.prevObject)}});c.each({parent:function(a){return(a=a.parentNode)&&a.nodeType!==11?a:null},parents:function(a){return c.dir(a,"parentNode")},parentsUntil:function(a,b,d){return c.dir(a,"parentNode", +d)},next:function(a){return c.nth(a,2,"nextSibling")},prev:function(a){return c.nth(a,2,"previousSibling")},nextAll:function(a){return c.dir(a,"nextSibling")},prevAll:function(a){return c.dir(a,"previousSibling")},nextUntil:function(a,b,d){return c.dir(a,"nextSibling",d)},prevUntil:function(a,b,d){return c.dir(a,"previousSibling",d)},siblings:function(a){return c.sibling(a.parentNode.firstChild,a)},children:function(a){return c.sibling(a.firstChild)},contents:function(a){return c.nodeName(a,"iframe")? +a.contentDocument||a.contentWindow.document:c.makeArray(a.childNodes)}},function(a,b){c.fn[a]=function(d,f){var e=c.map(this,b,d);eb.test(a)||(f=d);if(f&&typeof f==="string")e=c.filter(f,e);e=this.length>1?c.unique(e):e;if((this.length>1||gb.test(f))&&fb.test(a))e=e.reverse();return this.pushStack(e,a,R.call(arguments).join(","))}});c.extend({filter:function(a,b,d){if(d)a=":not("+a+")";return c.find.matches(a,b)},dir:function(a,b,d){var f=[];for(a=a[b];a&&a.nodeType!==9&&(d===w||a.nodeType!==1||!c(a).is(d));){a.nodeType=== +1&&f.push(a);a=a[b]}return f},nth:function(a,b,d){b=b||1;for(var f=0;a;a=a[d])if(a.nodeType===1&&++f===b)break;return a},sibling:function(a,b){for(var d=[];a;a=a.nextSibling)a.nodeType===1&&a!==b&&d.push(a);return d}});var Ja=/ jQuery\d+="(?:\d+|null)"/g,V=/^\s+/,Ka=/(<([\w:]+)[^>]*?)\/>/g,hb=/^(?:area|br|col|embed|hr|img|input|link|meta|param)$/i,La=/<([\w:]+)/,ib=/"},F={option:[1,""],legend:[1,"
","
"],thead:[1,"","
"],tr:[2,"","
"],td:[3,"","
"],col:[2,"","
"],area:[1,"",""],_default:[0,"",""]};F.optgroup=F.option;F.tbody=F.tfoot=F.colgroup=F.caption=F.thead;F.th=F.td;if(!c.support.htmlSerialize)F._default=[1,"div
","
"];c.fn.extend({text:function(a){if(c.isFunction(a))return this.each(function(b){var d= +c(this);d.text(a.call(this,b,d.text()))});if(typeof a!=="object"&&a!==w)return this.empty().append((this[0]&&this[0].ownerDocument||s).createTextNode(a));return c.text(this)},wrapAll:function(a){if(c.isFunction(a))return this.each(function(d){c(this).wrapAll(a.call(this,d))});if(this[0]){var b=c(a,this[0].ownerDocument).eq(0).clone(true);this[0].parentNode&&b.insertBefore(this[0]);b.map(function(){for(var d=this;d.firstChild&&d.firstChild.nodeType===1;)d=d.firstChild;return d}).append(this)}return this}, +wrapInner:function(a){if(c.isFunction(a))return this.each(function(b){c(this).wrapInner(a.call(this,b))});return this.each(function(){var b=c(this),d=b.contents();d.length?d.wrapAll(a):b.append(a)})},wrap:function(a){return this.each(function(){c(this).wrapAll(a)})},unwrap:function(){return this.parent().each(function(){c.nodeName(this,"body")||c(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.appendChild(a)})}, +prepend:function(){return this.domManip(arguments,true,function(a){this.nodeType===1&&this.insertBefore(a,this.firstChild)})},before:function(){if(this[0]&&this[0].parentNode)return this.domManip(arguments,false,function(b){this.parentNode.insertBefore(b,this)});else if(arguments.length){var a=c(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,false,function(b){this.parentNode.insertBefore(b, +this.nextSibling)});else if(arguments.length){var a=this.pushStack(this,"after",arguments);a.push.apply(a,c(arguments[0]).toArray());return a}},remove:function(a,b){for(var d=0,f;(f=this[d])!=null;d++)if(!a||c.filter(a,[f]).length){if(!b&&f.nodeType===1){c.cleanData(f.getElementsByTagName("*"));c.cleanData([f])}f.parentNode&&f.parentNode.removeChild(f)}return this},empty:function(){for(var a=0,b;(b=this[a])!=null;a++)for(b.nodeType===1&&c.cleanData(b.getElementsByTagName("*"));b.firstChild;)b.removeChild(b.firstChild); +return this},clone:function(a){var b=this.map(function(){if(!c.support.noCloneEvent&&!c.isXMLDoc(this)){var d=this.outerHTML,f=this.ownerDocument;if(!d){d=f.createElement("div");d.appendChild(this.cloneNode(true));d=d.innerHTML}return c.clean([d.replace(Ja,"").replace(/=([^="'>\s]+\/)>/g,'="$1">').replace(V,"")],f)[0]}else return this.cloneNode(true)});if(a===true){ra(this,b);ra(this.find("*"),b.find("*"))}return b},html:function(a){if(a===w)return this[0]&&this[0].nodeType===1?this[0].innerHTML.replace(Ja, +""):null;else if(typeof a==="string"&&!ta.test(a)&&(c.support.leadingWhitespace||!V.test(a))&&!F[(La.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(Ka,Ma);try{for(var b=0,d=this.length;b0||e.cacheable||this.length>1?k.cloneNode(true):k)}o.length&&c.each(o,Qa)}return this}});c.fragments={};c.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){c.fn[a]=function(d){var f=[];d=c(d);var e=this.length===1&&this[0].parentNode;if(e&&e.nodeType===11&&e.childNodes.length===1&&d.length===1){d[b](this[0]); +return this}else{e=0;for(var j=d.length;e0?this.clone(true):this).get();c.fn[b].apply(c(d[e]),i);f=f.concat(i)}return this.pushStack(f,a,d.selector)}}});c.extend({clean:function(a,b,d,f){b=b||s;if(typeof b.createElement==="undefined")b=b.ownerDocument||b[0]&&b[0].ownerDocument||s;for(var e=[],j=0,i;(i=a[j])!=null;j++){if(typeof i==="number")i+="";if(i){if(typeof i==="string"&&!jb.test(i))i=b.createTextNode(i);else if(typeof i==="string"){i=i.replace(Ka,Ma);var o=(La.exec(i)||["", +""])[1].toLowerCase(),k=F[o]||F._default,n=k[0],r=b.createElement("div");for(r.innerHTML=k[1]+i+k[2];n--;)r=r.lastChild;if(!c.support.tbody){n=ib.test(i);o=o==="table"&&!n?r.firstChild&&r.firstChild.childNodes:k[1]===""&&!n?r.childNodes:[];for(k=o.length-1;k>=0;--k)c.nodeName(o[k],"tbody")&&!o[k].childNodes.length&&o[k].parentNode.removeChild(o[k])}!c.support.leadingWhitespace&&V.test(i)&&r.insertBefore(b.createTextNode(V.exec(i)[0]),r.firstChild);i=r.childNodes}if(i.nodeType)e.push(i);else e= +c.merge(e,i)}}if(d)for(j=0;e[j];j++)if(f&&c.nodeName(e[j],"script")&&(!e[j].type||e[j].type.toLowerCase()==="text/javascript"))f.push(e[j].parentNode?e[j].parentNode.removeChild(e[j]):e[j]);else{e[j].nodeType===1&&e.splice.apply(e,[j+1,0].concat(c.makeArray(e[j].getElementsByTagName("script"))));d.appendChild(e[j])}return e},cleanData:function(a){for(var b,d,f=c.cache,e=c.event.special,j=c.support.deleteExpando,i=0,o;(o=a[i])!=null;i++)if(d=o[c.expando]){b=f[d];if(b.events)for(var k in b.events)e[k]? +c.event.remove(o,k):Ca(o,k,b.handle);if(j)delete o[c.expando];else o.removeAttribute&&o.removeAttribute(c.expando);delete f[d]}}});var kb=/z-?index|font-?weight|opacity|zoom|line-?height/i,Na=/alpha\([^)]*\)/,Oa=/opacity=([^)]*)/,ha=/float/i,ia=/-([a-z])/ig,lb=/([A-Z])/g,mb=/^-?\d+(?:px)?$/i,nb=/^-?\d/,ob={position:"absolute",visibility:"hidden",display:"block"},pb=["Left","Right"],qb=["Top","Bottom"],rb=s.defaultView&&s.defaultView.getComputedStyle,Pa=c.support.cssFloat?"cssFloat":"styleFloat",ja= +function(a,b){return b.toUpperCase()};c.fn.css=function(a,b){return X(this,a,b,true,function(d,f,e){if(e===w)return c.curCSS(d,f);if(typeof e==="number"&&!kb.test(f))e+="px";c.style(d,f,e)})};c.extend({style:function(a,b,d){if(!a||a.nodeType===3||a.nodeType===8)return w;if((b==="width"||b==="height")&&parseFloat(d)<0)d=w;var f=a.style||a,e=d!==w;if(!c.support.opacity&&b==="opacity"){if(e){f.zoom=1;b=parseInt(d,10)+""==="NaN"?"":"alpha(opacity="+d*100+")";a=f.filter||c.curCSS(a,"filter")||"";f.filter= +Na.test(a)?a.replace(Na,b):b}return f.filter&&f.filter.indexOf("opacity=")>=0?parseFloat(Oa.exec(f.filter)[1])/100+"":""}if(ha.test(b))b=Pa;b=b.replace(ia,ja);if(e)f[b]=d;return f[b]},css:function(a,b,d,f){if(b==="width"||b==="height"){var e,j=b==="width"?pb:qb;function i(){e=b==="width"?a.offsetWidth:a.offsetHeight;f!=="border"&&c.each(j,function(){f||(e-=parseFloat(c.curCSS(a,"padding"+this,true))||0);if(f==="margin")e+=parseFloat(c.curCSS(a,"margin"+this,true))||0;else e-=parseFloat(c.curCSS(a, +"border"+this+"Width",true))||0})}a.offsetWidth!==0?i():c.swap(a,ob,i);return Math.max(0,Math.round(e))}return c.curCSS(a,b,d)},curCSS:function(a,b,d){var f,e=a.style;if(!c.support.opacity&&b==="opacity"&&a.currentStyle){f=Oa.test(a.currentStyle.filter||"")?parseFloat(RegExp.$1)/100+"":"";return f===""?"1":f}if(ha.test(b))b=Pa;if(!d&&e&&e[b])f=e[b];else if(rb){if(ha.test(b))b="float";b=b.replace(lb,"-$1").toLowerCase();e=a.ownerDocument.defaultView;if(!e)return null;if(a=e.getComputedStyle(a,null))f= +a.getPropertyValue(b);if(b==="opacity"&&f==="")f="1"}else if(a.currentStyle){d=b.replace(ia,ja);f=a.currentStyle[b]||a.currentStyle[d];if(!mb.test(f)&&nb.test(f)){b=e.left;var j=a.runtimeStyle.left;a.runtimeStyle.left=a.currentStyle.left;e.left=d==="fontSize"?"1em":f||0;f=e.pixelLeft+"px";e.left=b;a.runtimeStyle.left=j}}return f},swap:function(a,b,d){var f={};for(var e in b){f[e]=a.style[e];a.style[e]=b[e]}d.call(a);for(e in b)a.style[e]=f[e]}});if(c.expr&&c.expr.filters){c.expr.filters.hidden=function(a){var b= +a.offsetWidth,d=a.offsetHeight,f=a.nodeName.toLowerCase()==="tr";return b===0&&d===0&&!f?true:b>0&&d>0&&!f?false:c.curCSS(a,"display")==="none"};c.expr.filters.visible=function(a){return!c.expr.filters.hidden(a)}}var sb=J(),tb=//gi,ub=/select|textarea/i,vb=/color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i,N=/=\?(&|$)/,ka=/\?/,wb=/(\?|&)_=.*?(&|$)/,xb=/^(\w+:)?\/\/([^\/?#]+)/,yb=/%20/g,zb=c.fn.load;c.fn.extend({load:function(a,b,d){if(typeof a!== +"string")return zb.call(this,a);else if(!this.length)return this;var f=a.indexOf(" ");if(f>=0){var e=a.slice(f,a.length);a=a.slice(0,f)}f="GET";if(b)if(c.isFunction(b)){d=b;b=null}else if(typeof b==="object"){b=c.param(b,c.ajaxSettings.traditional);f="POST"}var j=this;c.ajax({url:a,type:f,dataType:"html",data:b,complete:function(i,o){if(o==="success"||o==="notmodified")j.html(e?c("
").append(i.responseText.replace(tb,"")).find(e):i.responseText);d&&j.each(d,[i.responseText,o,i])}});return this}, +serialize:function(){return c.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?c.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||ub.test(this.nodeName)||vb.test(this.type))}).map(function(a,b){a=c(this).val();return a==null?null:c.isArray(a)?c.map(a,function(d){return{name:b.name,value:d}}):{name:b.name,value:a}}).get()}});c.each("ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split(" "), +function(a,b){c.fn[b]=function(d){return this.bind(b,d)}});c.extend({get:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b=null}return c.ajax({type:"GET",url:a,data:b,success:d,dataType:f})},getScript:function(a,b){return c.get(a,null,b,"script")},getJSON:function(a,b,d){return c.get(a,b,d,"json")},post:function(a,b,d,f){if(c.isFunction(b)){f=f||d;d=b;b={}}return c.ajax({type:"POST",url:a,data:b,success:d,dataType:f})},ajaxSetup:function(a){c.extend(c.ajaxSettings,a)},ajaxSettings:{url:location.href, +global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:A.XMLHttpRequest&&(A.location.protocol!=="file:"||!A.ActiveXObject)?function(){return new A.XMLHttpRequest}:function(){try{return new A.ActiveXObject("Microsoft.XMLHTTP")}catch(a){}},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},etag:{},ajax:function(a){function b(){e.success&& +e.success.call(k,o,i,x);e.global&&f("ajaxSuccess",[x,e])}function d(){e.complete&&e.complete.call(k,x,i);e.global&&f("ajaxComplete",[x,e]);e.global&&!--c.active&&c.event.trigger("ajaxStop")}function f(q,p){(e.context?c(e.context):c.event).trigger(q,p)}var e=c.extend(true,{},c.ajaxSettings,a),j,i,o,k=a&&a.context||e,n=e.type.toUpperCase();if(e.data&&e.processData&&typeof e.data!=="string")e.data=c.param(e.data,e.traditional);if(e.dataType==="jsonp"){if(n==="GET")N.test(e.url)||(e.url+=(ka.test(e.url)? +"&":"?")+(e.jsonp||"callback")+"=?");else if(!e.data||!N.test(e.data))e.data=(e.data?e.data+"&":"")+(e.jsonp||"callback")+"=?";e.dataType="json"}if(e.dataType==="json"&&(e.data&&N.test(e.data)||N.test(e.url))){j=e.jsonpCallback||"jsonp"+sb++;if(e.data)e.data=(e.data+"").replace(N,"="+j+"$1");e.url=e.url.replace(N,"="+j+"$1");e.dataType="script";A[j]=A[j]||function(q){o=q;b();d();A[j]=w;try{delete A[j]}catch(p){}z&&z.removeChild(C)}}if(e.dataType==="script"&&e.cache===null)e.cache=false;if(e.cache=== +false&&n==="GET"){var r=J(),u=e.url.replace(wb,"$1_="+r+"$2");e.url=u+(u===e.url?(ka.test(e.url)?"&":"?")+"_="+r:"")}if(e.data&&n==="GET")e.url+=(ka.test(e.url)?"&":"?")+e.data;e.global&&!c.active++&&c.event.trigger("ajaxStart");r=(r=xb.exec(e.url))&&(r[1]&&r[1]!==location.protocol||r[2]!==location.host);if(e.dataType==="script"&&n==="GET"&&r){var z=s.getElementsByTagName("head")[0]||s.documentElement,C=s.createElement("script");C.src=e.url;if(e.scriptCharset)C.charset=e.scriptCharset;if(!j){var B= +false;C.onload=C.onreadystatechange=function(){if(!B&&(!this.readyState||this.readyState==="loaded"||this.readyState==="complete")){B=true;b();d();C.onload=C.onreadystatechange=null;z&&C.parentNode&&z.removeChild(C)}}}z.insertBefore(C,z.firstChild);return w}var E=false,x=e.xhr();if(x){e.username?x.open(n,e.url,e.async,e.username,e.password):x.open(n,e.url,e.async);try{if(e.data||a&&a.contentType)x.setRequestHeader("Content-Type",e.contentType);if(e.ifModified){c.lastModified[e.url]&&x.setRequestHeader("If-Modified-Since", +c.lastModified[e.url]);c.etag[e.url]&&x.setRequestHeader("If-None-Match",c.etag[e.url])}r||x.setRequestHeader("X-Requested-With","XMLHttpRequest");x.setRequestHeader("Accept",e.dataType&&e.accepts[e.dataType]?e.accepts[e.dataType]+", */*":e.accepts._default)}catch(ga){}if(e.beforeSend&&e.beforeSend.call(k,x,e)===false){e.global&&!--c.active&&c.event.trigger("ajaxStop");x.abort();return false}e.global&&f("ajaxSend",[x,e]);var g=x.onreadystatechange=function(q){if(!x||x.readyState===0||q==="abort"){E|| +d();E=true;if(x)x.onreadystatechange=c.noop}else if(!E&&x&&(x.readyState===4||q==="timeout")){E=true;x.onreadystatechange=c.noop;i=q==="timeout"?"timeout":!c.httpSuccess(x)?"error":e.ifModified&&c.httpNotModified(x,e.url)?"notmodified":"success";var p;if(i==="success")try{o=c.httpData(x,e.dataType,e)}catch(v){i="parsererror";p=v}if(i==="success"||i==="notmodified")j||b();else c.handleError(e,x,i,p);d();q==="timeout"&&x.abort();if(e.async)x=null}};try{var h=x.abort;x.abort=function(){x&&h.call(x); +g("abort")}}catch(l){}e.async&&e.timeout>0&&setTimeout(function(){x&&!E&&g("timeout")},e.timeout);try{x.send(n==="POST"||n==="PUT"||n==="DELETE"?e.data:null)}catch(m){c.handleError(e,x,null,m);d()}e.async||g();return x}},handleError:function(a,b,d,f){if(a.error)a.error.call(a.context||a,b,d,f);if(a.global)(a.context?c(a.context):c.event).trigger("ajaxError",[b,a,f])},active:0,httpSuccess:function(a){try{return!a.status&&location.protocol==="file:"||a.status>=200&&a.status<300||a.status===304||a.status=== +1223||a.status===0}catch(b){}return false},httpNotModified:function(a,b){var d=a.getResponseHeader("Last-Modified"),f=a.getResponseHeader("Etag");if(d)c.lastModified[b]=d;if(f)c.etag[b]=f;return a.status===304||a.status===0},httpData:function(a,b,d){var f=a.getResponseHeader("content-type")||"",e=b==="xml"||!b&&f.indexOf("xml")>=0;a=e?a.responseXML:a.responseText;e&&a.documentElement.nodeName==="parsererror"&&c.error("parsererror");if(d&&d.dataFilter)a=d.dataFilter(a,b);if(typeof a==="string")if(b=== +"json"||!b&&f.indexOf("json")>=0)a=c.parseJSON(a);else if(b==="script"||!b&&f.indexOf("javascript")>=0)c.globalEval(a);return a},param:function(a,b){function d(i,o){if(c.isArray(o))c.each(o,function(k,n){b||/\[\]$/.test(i)?f(i,n):d(i+"["+(typeof n==="object"||c.isArray(n)?k:"")+"]",n)});else!b&&o!=null&&typeof o==="object"?c.each(o,function(k,n){d(i+"["+k+"]",n)}):f(i,o)}function f(i,o){o=c.isFunction(o)?o():o;e[e.length]=encodeURIComponent(i)+"="+encodeURIComponent(o)}var e=[];if(b===w)b=c.ajaxSettings.traditional; +if(c.isArray(a)||a.jquery)c.each(a,function(){f(this.name,this.value)});else for(var j in a)d(j,a[j]);return e.join("&").replace(yb,"+")}});var la={},Ab=/toggle|show|hide/,Bb=/^([+-]=)?([\d+-.]+)(.*)$/,W,va=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];c.fn.extend({show:function(a,b){if(a||a===0)return this.animate(K("show",3),a,b);else{a=0;for(b=this.length;a").appendTo("body");f=e.css("display");if(f==="none")f="block";e.remove();la[d]=f}c.data(this[a],"olddisplay",f)}}a=0;for(b=this.length;a=0;f--)if(d[f].elem===this){b&&d[f](true);d.splice(f,1)}});b||this.dequeue();return this}});c.each({slideDown:K("show",1),slideUp:K("hide",1),slideToggle:K("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(a,b){c.fn[a]=function(d,f){return this.animate(b,d,f)}});c.extend({speed:function(a,b,d){var f=a&&typeof a==="object"?a:{complete:d||!d&&b||c.isFunction(a)&&a,duration:a,easing:d&&b||b&&!c.isFunction(b)&&b};f.duration=c.fx.off?0:typeof f.duration=== +"number"?f.duration:c.fx.speeds[f.duration]||c.fx.speeds._default;f.old=f.complete;f.complete=function(){f.queue!==false&&c(this).dequeue();c.isFunction(f.old)&&f.old.call(this)};return f},easing:{linear:function(a,b,d,f){return d+f*a},swing:function(a,b,d,f){return(-Math.cos(a*Math.PI)/2+0.5)*f+d}},timers:[],fx:function(a,b,d){this.options=b;this.elem=a;this.prop=d;if(!b.orig)b.orig={}}});c.fx.prototype={update:function(){this.options.step&&this.options.step.call(this.elem,this.now,this);(c.fx.step[this.prop]|| +c.fx.step._default)(this);if((this.prop==="height"||this.prop==="width")&&this.elem.style)this.elem.style.display="block"},cur:function(a){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null))return this.elem[this.prop];return(a=parseFloat(c.css(this.elem,this.prop,a)))&&a>-10000?a:parseFloat(c.curCSS(this.elem,this.prop))||0},custom:function(a,b,d){function f(j){return e.step(j)}this.startTime=J();this.start=a;this.end=b;this.unit=d||this.unit||"px";this.now=this.start; +this.pos=this.state=0;var e=this;f.elem=this.elem;if(f()&&c.timers.push(f)&&!W)W=setInterval(c.fx.tick,13)},show:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.show=true;this.custom(this.prop==="width"||this.prop==="height"?1:0,this.cur());c(this.elem).show()},hide:function(){this.options.orig[this.prop]=c.style(this.elem,this.prop);this.options.hide=true;this.custom(this.cur(),0)},step:function(a){var b=J(),d=true;if(a||b>=this.options.duration+this.startTime){this.now= +this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;for(var f in this.options.curAnim)if(this.options.curAnim[f]!==true)d=false;if(d){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;a=c.data(this.elem,"olddisplay");this.elem.style.display=a?a:this.options.display;if(c.css(this.elem,"display")==="none")this.elem.style.display="block"}this.options.hide&&c(this.elem).hide();if(this.options.hide||this.options.show)for(var e in this.options.curAnim)c.style(this.elem, +e,this.options.orig[e]);this.options.complete.call(this.elem)}return false}else{e=b-this.startTime;this.state=e/this.options.duration;a=this.options.easing||(c.easing.swing?"swing":"linear");this.pos=c.easing[this.options.specialEasing&&this.options.specialEasing[this.prop]||a](this.state,e,0,1,this.options.duration);this.now=this.start+(this.end-this.start)*this.pos;this.update()}return true}};c.extend(c.fx,{tick:function(){for(var a=c.timers,b=0;b
"; +a.insertBefore(b,a.firstChild);d=b.firstChild;f=d.firstChild;e=d.nextSibling.firstChild.firstChild;this.doesNotAddBorder=f.offsetTop!==5;this.doesAddBorderForTableAndCells=e.offsetTop===5;f.style.position="fixed";f.style.top="20px";this.supportsFixedPosition=f.offsetTop===20||f.offsetTop===15;f.style.position=f.style.top="";d.style.overflow="hidden";d.style.position="relative";this.subtractsBorderForOverflowNotVisible=f.offsetTop===-5;this.doesNotIncludeMarginInBodyOffset=a.offsetTop!==j;a.removeChild(b); +c.offset.initialize=c.noop},bodyOffset:function(a){var b=a.offsetTop,d=a.offsetLeft;c.offset.initialize();if(c.offset.doesNotIncludeMarginInBodyOffset){b+=parseFloat(c.curCSS(a,"marginTop",true))||0;d+=parseFloat(c.curCSS(a,"marginLeft",true))||0}return{top:b,left:d}},setOffset:function(a,b,d){if(/static/.test(c.curCSS(a,"position")))a.style.position="relative";var f=c(a),e=f.offset(),j=parseInt(c.curCSS(a,"top",true),10)||0,i=parseInt(c.curCSS(a,"left",true),10)||0;if(c.isFunction(b))b=b.call(a, +d,e);d={top:b.top-e.top+j,left:b.left-e.left+i};"using"in b?b.using.call(a,d):f.css(d)}};c.fn.extend({position:function(){if(!this[0])return null;var a=this[0],b=this.offsetParent(),d=this.offset(),f=/^body|html$/i.test(b[0].nodeName)?{top:0,left:0}:b.offset();d.top-=parseFloat(c.curCSS(a,"marginTop",true))||0;d.left-=parseFloat(c.curCSS(a,"marginLeft",true))||0;f.top+=parseFloat(c.curCSS(b[0],"borderTopWidth",true))||0;f.left+=parseFloat(c.curCSS(b[0],"borderLeftWidth",true))||0;return{top:d.top- +f.top,left:d.left-f.left}},offsetParent:function(){return this.map(function(){for(var a=this.offsetParent||s.body;a&&!/^body|html$/i.test(a.nodeName)&&c.css(a,"position")==="static";)a=a.offsetParent;return a})}});c.each(["Left","Top"],function(a,b){var d="scroll"+b;c.fn[d]=function(f){var e=this[0],j;if(!e)return null;if(f!==w)return this.each(function(){if(j=wa(this))j.scrollTo(!a?f:c(j).scrollLeft(),a?f:c(j).scrollTop());else this[d]=f});else return(j=wa(e))?"pageXOffset"in j?j[a?"pageYOffset": +"pageXOffset"]:c.support.boxModel&&j.document.documentElement[d]||j.document.body[d]:e[d]}});c.each(["Height","Width"],function(a,b){var d=b.toLowerCase();c.fn["inner"+b]=function(){return this[0]?c.css(this[0],d,false,"padding"):null};c.fn["outer"+b]=function(f){return this[0]?c.css(this[0],d,false,f?"margin":"border"):null};c.fn[d]=function(f){var e=this[0];if(!e)return f==null?null:this;if(c.isFunction(f))return this.each(function(j){var i=c(this);i[d](f.call(this,j,i[d]()))});return"scrollTo"in +e&&e.document?e.document.compatMode==="CSS1Compat"&&e.document.documentElement["client"+b]||e.document.body["client"+b]:e.nodeType===9?Math.max(e.documentElement["client"+b],e.body["scroll"+b],e.documentElement["scroll"+b],e.body["offset"+b],e.documentElement["offset"+b]):f===w?c.css(e,d):this.css(d,typeof f==="string"?f:f+"px")}});A.jQuery=A.$=c})(window); diff --git a/spec/test_app/public/javascripts/jquery-ui.js b/spec/test_app/public/javascripts/jquery-ui.js new file mode 100644 index 0000000..3efce20 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery-ui.js @@ -0,0 +1,188 @@ +/* + * jQuery UI 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI + */ +jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;/* + * jQuery UI Draggable 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Draggables + * + * Depends: + * ui.core.js + */ +(function(a){a.widget("ui.draggable",a.extend({},a.ui.mouse,{_init:function(){if(this.options.helper=="original"&&!(/^(?:r|a|f)/).test(this.element.css("position"))){this.element[0].style.position="relative"}(this.options.addClasses&&this.element.addClass("ui-draggable"));(this.options.disabled&&this.element.addClass("ui-draggable-disabled"));this._mouseInit()},destroy:function(){if(!this.element.data("draggable")){return}this.element.removeData("draggable").unbind(".draggable").removeClass("ui-draggable ui-draggable-dragging ui-draggable-disabled");this._mouseDestroy()},_mouseCapture:function(b){var c=this.options;if(this.helper||c.disabled||a(b.target).is(".ui-resizable-handle")){return false}this.handle=this._getHandle(b);if(!this.handle){return false}return true},_mouseStart:function(b){var c=this.options;this.helper=this._createHelper(b);this._cacheHelperProportions();if(a.ui.ddmanager){a.ui.ddmanager.current=this}this._cacheMargins();this.cssPosition=this.helper.css("position");this.scrollParent=this.helper.scrollParent();this.offset=this.element.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};a.extend(this.offset,{click:{left:b.pageX-this.offset.left,top:b.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(b);this.originalPageX=b.pageX;this.originalPageY=b.pageY;if(c.cursorAt){this._adjustOffsetFromHelper(c.cursorAt)}if(c.containment){this._setContainment()}this._trigger("start",b);this._cacheHelperProportions();if(a.ui.ddmanager&&!c.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,b)}this.helper.addClass("ui-draggable-dragging");this._mouseDrag(b,true);return true},_mouseDrag:function(b,d){this.position=this._generatePosition(b);this.positionAbs=this._convertPositionTo("absolute");if(!d){var c=this._uiHash();this._trigger("drag",b,c);this.position=c.position}if(!this.options.axis||this.options.axis!="y"){this.helper[0].style.left=this.position.left+"px"}if(!this.options.axis||this.options.axis!="x"){this.helper[0].style.top=this.position.top+"px"}if(a.ui.ddmanager){a.ui.ddmanager.drag(this,b)}return false},_mouseStop:function(c){var d=false;if(a.ui.ddmanager&&!this.options.dropBehaviour){d=a.ui.ddmanager.drop(this,c)}if(this.dropped){d=this.dropped;this.dropped=false}if((this.options.revert=="invalid"&&!d)||(this.options.revert=="valid"&&d)||this.options.revert===true||(a.isFunction(this.options.revert)&&this.options.revert.call(this.element,d))){var b=this;a(this.helper).animate(this.originalPosition,parseInt(this.options.revertDuration,10),function(){b._trigger("stop",c);b._clear()})}else{this._trigger("stop",c);this._clear()}return false},_getHandle:function(b){var c=!this.options.handle||!a(this.options.handle,this.element).length?true:false;a(this.options.handle,this.element).find("*").andSelf().each(function(){if(this==b.target){c=true}});return c},_createHelper:function(c){var d=this.options;var b=a.isFunction(d.helper)?a(d.helper.apply(this.element[0],[c])):(d.helper=="clone"?this.element.clone():this.element);if(!b.parents("body").length){b.appendTo((d.appendTo=="parent"?this.element[0].parentNode:d.appendTo))}if(b[0]!=this.element[0]&&!(/(fixed|absolute)/).test(b.css("position"))){b.css("position","absolute")}return b},_adjustOffsetFromHelper:function(b){if(b.left!=undefined){this.offset.click.left=b.left+this.margins.left}if(b.right!=undefined){this.offset.click.left=this.helperProportions.width-b.right+this.margins.left}if(b.top!=undefined){this.offset.click.top=b.top+this.margins.top}if(b.bottom!=undefined){this.offset.click.top=this.helperProportions.height-b.bottom+this.margins.top}},_getParentOffset:function(){this.offsetParent=this.helper.offsetParent();var b=this.offsetParent.offset();if(this.cssPosition=="absolute"&&this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0])){b.left+=this.scrollParent.scrollLeft();b.top+=this.scrollParent.scrollTop()}if((this.offsetParent[0]==document.body)||(this.offsetParent[0].tagName&&this.offsetParent[0].tagName.toLowerCase()=="html"&&a.browser.msie)){b={top:0,left:0}}return{top:b.top+(parseInt(this.offsetParent.css("borderTopWidth"),10)||0),left:b.left+(parseInt(this.offsetParent.css("borderLeftWidth"),10)||0)}},_getRelativeOffset:function(){if(this.cssPosition=="relative"){var b=this.element.position();return{top:b.top-(parseInt(this.helper.css("top"),10)||0)+this.scrollParent.scrollTop(),left:b.left-(parseInt(this.helper.css("left"),10)||0)+this.scrollParent.scrollLeft()}}else{return{top:0,left:0}}},_cacheMargins:function(){this.margins={left:(parseInt(this.element.css("marginLeft"),10)||0),top:(parseInt(this.element.css("marginTop"),10)||0)}},_cacheHelperProportions:function(){this.helperProportions={width:this.helper.outerWidth(),height:this.helper.outerHeight()}},_setContainment:function(){var e=this.options;if(e.containment=="parent"){e.containment=this.helper[0].parentNode}if(e.containment=="document"||e.containment=="window"){this.containment=[0-this.offset.relative.left-this.offset.parent.left,0-this.offset.relative.top-this.offset.parent.top,a(e.containment=="document"?document:window).width()-this.helperProportions.width-this.margins.left,(a(e.containment=="document"?document:window).height()||document.body.parentNode.scrollHeight)-this.helperProportions.height-this.margins.top]}if(!(/^(document|window|parent)$/).test(e.containment)&&e.containment.constructor!=Array){var c=a(e.containment)[0];if(!c){return}var d=a(e.containment).offset();var b=(a(c).css("overflow")!="hidden");this.containment=[d.left+(parseInt(a(c).css("borderLeftWidth"),10)||0)+(parseInt(a(c).css("paddingLeft"),10)||0)-this.margins.left,d.top+(parseInt(a(c).css("borderTopWidth"),10)||0)+(parseInt(a(c).css("paddingTop"),10)||0)-this.margins.top,d.left+(b?Math.max(c.scrollWidth,c.offsetWidth):c.offsetWidth)-(parseInt(a(c).css("borderLeftWidth"),10)||0)-(parseInt(a(c).css("paddingRight"),10)||0)-this.helperProportions.width-this.margins.left,d.top+(b?Math.max(c.scrollHeight,c.offsetHeight):c.offsetHeight)-(parseInt(a(c).css("borderTopWidth"),10)||0)-(parseInt(a(c).css("paddingBottom"),10)||0)-this.helperProportions.height-this.margins.top]}else{if(e.containment.constructor==Array){this.containment=e.containment}}},_convertPositionTo:function(f,h){if(!h){h=this.position}var c=f=="absolute"?1:-1;var e=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,g=(/(html|body)/i).test(b[0].tagName);return{top:(h.top+this.offset.relative.top*c+this.offset.parent.top*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollTop():(g?0:b.scrollTop()))*c)),left:(h.left+this.offset.relative.left*c+this.offset.parent.left*c-(a.browser.safari&&this.cssPosition=="fixed"?0:(this.cssPosition=="fixed"?-this.scrollParent.scrollLeft():g?0:b.scrollLeft())*c))}},_generatePosition:function(e){var h=this.options,b=this.cssPosition=="absolute"&&!(this.scrollParent[0]!=document&&a.ui.contains(this.scrollParent[0],this.offsetParent[0]))?this.offsetParent:this.scrollParent,i=(/(html|body)/i).test(b[0].tagName);if(this.cssPosition=="relative"&&!(this.scrollParent[0]!=document&&this.scrollParent[0]!=this.offsetParent[0])){this.offset.relative=this._getRelativeOffset()}var d=e.pageX;var c=e.pageY;if(this.originalPosition){if(this.containment){if(e.pageX-this.offset.click.leftthis.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.topthis.containment[3])?g:(!(g-this.offset.click.topthis.containment[2])?f:(!(f-this.offset.click.left').css({width:this.offsetWidth+"px",height:this.offsetHeight+"px",position:"absolute",opacity:"0.001",zIndex:1000}).css(a(this).offset()).appendTo("body")})},stop:function(b,c){a("div.ui-draggable-iframeFix").each(function(){this.parentNode.removeChild(this)})}});a.ui.plugin.add("draggable","opacity",{start:function(c,d){var b=a(d.helper),e=a(this).data("draggable").options;if(b.css("opacity")){e._opacity=b.css("opacity")}b.css("opacity",e.opacity)},stop:function(b,c){var d=a(this).data("draggable").options;if(d._opacity){a(c.helper).css("opacity",d._opacity)}}});a.ui.plugin.add("draggable","scroll",{start:function(c,d){var b=a(this).data("draggable");if(b.scrollParent[0]!=document&&b.scrollParent[0].tagName!="HTML"){b.overflowOffset=b.scrollParent.offset()}},drag:function(d,e){var c=a(this).data("draggable"),f=c.options,b=false;if(c.scrollParent[0]!=document&&c.scrollParent[0].tagName!="HTML"){if(!f.axis||f.axis!="x"){if((c.overflowOffset.top+c.scrollParent[0].offsetHeight)-d.pageY=0;v--){var s=g.snapElements[v].left,n=s+g.snapElements[v].width,m=g.snapElements[v].top,A=m+g.snapElements[v].height;if(!((s-y=p&&n<=k)||(m>=p&&m<=k)||(nk))&&((e>=g&&e<=c)||(d>=g&&d<=c)||(ec));break;default:return false;break}};a.ui.ddmanager={current:null,droppables:{"default":[]},prepareOffsets:function(e,g){var b=a.ui.ddmanager.droppables[e.options.scope];var f=g?g.type:null;var h=(e.currentItem||e.element).find(":data(droppable)").andSelf();droppablesLoop:for(var d=0;d=0;b--){this.items[b].item.removeData("sortable-item")}},_mouseCapture:function(e,f){if(this.reverting){return false}if(this.options.disabled||this.options.type=="static"){return false}this._refreshItems(e);var d=null,c=this,b=a(e.target).parents().each(function(){if(a.data(this,"sortable-item")==c){d=a(this);return false}});if(a.data(e.target,"sortable-item")==c){d=a(e.target)}if(!d){return false}if(this.options.handle&&!f){var g=false;a(this.options.handle,d).find("*").andSelf().each(function(){if(this==e.target){g=true}});if(!g){return false}}this.currentItem=d;this._removeCurrentsFromItems();return true},_mouseStart:function(e,f,b){var g=this.options,c=this;this.currentContainer=this;this.refreshPositions();this.helper=this._createHelper(e);this._cacheHelperProportions();this._cacheMargins();this.scrollParent=this.helper.scrollParent();this.offset=this.currentItem.offset();this.offset={top:this.offset.top-this.margins.top,left:this.offset.left-this.margins.left};this.helper.css("position","absolute");this.cssPosition=this.helper.css("position");a.extend(this.offset,{click:{left:e.pageX-this.offset.left,top:e.pageY-this.offset.top},parent:this._getParentOffset(),relative:this._getRelativeOffset()});this.originalPosition=this._generatePosition(e);this.originalPageX=e.pageX;this.originalPageY=e.pageY;if(g.cursorAt){this._adjustOffsetFromHelper(g.cursorAt)}this.domPosition={prev:this.currentItem.prev()[0],parent:this.currentItem.parent()[0]};if(this.helper[0]!=this.currentItem[0]){this.currentItem.hide()}this._createPlaceholder();if(g.containment){this._setContainment()}if(g.cursor){if(a("body").css("cursor")){this._storedCursor=a("body").css("cursor")}a("body").css("cursor",g.cursor)}if(g.opacity){if(this.helper.css("opacity")){this._storedOpacity=this.helper.css("opacity")}this.helper.css("opacity",g.opacity)}if(g.zIndex){if(this.helper.css("zIndex")){this._storedZIndex=this.helper.css("zIndex")}this.helper.css("zIndex",g.zIndex)}if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){this.overflowOffset=this.scrollParent.offset()}this._trigger("start",e,this._uiHash());if(!this._preserveHelperProportions){this._cacheHelperProportions()}if(!b){for(var d=this.containers.length-1;d>=0;d--){this.containers[d]._trigger("activate",e,c._uiHash(this))}}if(a.ui.ddmanager){a.ui.ddmanager.current=this}if(a.ui.ddmanager&&!g.dropBehaviour){a.ui.ddmanager.prepareOffsets(this,e)}this.dragging=true;this.helper.addClass("ui-sortable-helper");this._mouseDrag(e);return true},_mouseDrag:function(f){this.position=this._generatePosition(f);this.positionAbs=this._convertPositionTo("absolute");if(!this.lastPositionAbs){this.lastPositionAbs=this.positionAbs}if(this.options.scroll){var g=this.options,b=false;if(this.scrollParent[0]!=document&&this.scrollParent[0].tagName!="HTML"){if((this.overflowOffset.top+this.scrollParent[0].offsetHeight)-f.pageY=0;d--){var e=this.items[d],c=e.item[0],h=this._intersectsWithPointer(e);if(!h){continue}if(c!=this.currentItem[0]&&this.placeholder[h==1?"next":"prev"]()[0]!=c&&!a.ui.contains(this.placeholder[0],c)&&(this.options.type=="semi-dynamic"?!a.ui.contains(this.element[0],c):true)){this.direction=h==1?"down":"up";if(this.options.tolerance=="pointer"||this._intersectsWithSides(e)){this._rearrange(f,e)}else{break}this._trigger("change",f,this._uiHash());break}}this._contactContainers(f);if(a.ui.ddmanager){a.ui.ddmanager.drag(this,f)}this._trigger("sort",f,this._uiHash());this.lastPositionAbs=this.positionAbs;return false},_mouseStop:function(c,d){if(!c){return}if(a.ui.ddmanager&&!this.options.dropBehaviour){a.ui.ddmanager.drop(this,c)}if(this.options.revert){var b=this;var e=b.placeholder.offset();b.reverting=true;a(this.helper).animate({left:e.left-this.offset.parent.left-b.margins.left+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollLeft),top:e.top-this.offset.parent.top-b.margins.top+(this.offsetParent[0]==document.body?0:this.offsetParent[0].scrollTop)},parseInt(this.options.revert,10)||500,function(){b._clear(c)})}else{this._clear(c,d)}return false},cancel:function(){var b=this;if(this.dragging){this._mouseUp();if(this.options.helper=="original"){this.currentItem.css(this._storedCSS).removeClass("ui-sortable-helper")}else{this.currentItem.show()}for(var c=this.containers.length-1;c>=0;c--){this.containers[c]._trigger("deactivate",null,b._uiHash(this));if(this.containers[c].containerCache.over){this.containers[c]._trigger("out",null,b._uiHash(this));this.containers[c].containerCache.over=0}}}if(this.placeholder[0].parentNode){this.placeholder[0].parentNode.removeChild(this.placeholder[0])}if(this.options.helper!="original"&&this.helper&&this.helper[0].parentNode){this.helper.remove()}a.extend(this,{helper:null,dragging:false,reverting:false,_noFinalSort:null});if(this.domPosition.prev){a(this.domPosition.prev).after(this.currentItem)}else{a(this.domPosition.parent).prepend(this.currentItem)}return true},serialize:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};a(b).each(function(){var e=(a(d.item||this).attr(d.attribute||"id")||"").match(d.expression||(/(.+)[-=_](.+)/));if(e){c.push((d.key||e[1]+"[]")+"="+(d.key&&d.expression?e[1]:e[2]))}});return c.join("&")},toArray:function(d){var b=this._getItemsAsjQuery(d&&d.connected);var c=[];d=d||{};b.each(function(){c.push(a(d.item||this).attr(d.attribute||"id")||"")});return c},_intersectsWith:function(m){var e=this.positionAbs.left,d=e+this.helperProportions.width,k=this.positionAbs.top,j=k+this.helperProportions.height;var f=m.left,c=f+m.width,n=m.top,i=n+m.height;var o=this.offset.click.top,h=this.offset.click.left;var g=(k+o)>n&&(k+o)f&&(e+h)m[this.floating?"width":"height"])){return g}else{return(f0?"down":"up")},_getDragHorizontalDirection:function(){var b=this.positionAbs.left-this.lastPositionAbs.left;return b!=0&&(b>0?"right":"left")},refresh:function(b){this._refreshItems(b);this.refreshPositions()},_connectWith:function(){var b=this.options;return b.connectWith.constructor==String?[b.connectWith]:b.connectWith},_getItemsAsjQuery:function(b){var l=this;var g=[];var e=[];var h=this._connectWith();if(h&&b){for(var d=h.length-1;d>=0;d--){var k=a(h[d]);for(var c=k.length-1;c>=0;c--){var f=a.data(k[c],"sortable");if(f&&f!=this&&!f.options.disabled){e.push([a.isFunction(f.options.items)?f.options.items.call(f.element):a(f.options.items,f.element).not(".ui-sortable-helper"),f])}}}}e.push([a.isFunction(this.options.items)?this.options.items.call(this.element,null,{options:this.options,item:this.currentItem}):a(this.options.items,this.element).not(".ui-sortable-helper"),this]);for(var d=e.length-1;d>=0;d--){e[d][0].each(function(){g.push(this)})}return a(g)},_removeCurrentsFromItems:function(){var d=this.currentItem.find(":data(sortable-item)");for(var c=0;c=0;e--){var m=a(l[e]);for(var d=m.length-1;d>=0;d--){var g=a.data(m[d],"sortable");if(g&&g!=this&&!g.options.disabled){f.push([a.isFunction(g.options.items)?g.options.items.call(g.element[0],b,{item:this.currentItem}):a(g.options.items,g.element),g]);this.containers.push(g)}}}}for(var e=f.length-1;e>=0;e--){var k=f[e][1];var c=f[e][0];for(var d=0,n=c.length;d=0;d--){var e=this.items[d];if(e.instance!=this.currentContainer&&this.currentContainer&&e.item[0]!=this.currentItem[0]){continue}var c=this.options.toleranceElement?a(this.options.toleranceElement,e.item):e.item;if(!b){e.width=c.outerWidth();e.height=c.outerHeight()}var f=c.offset();e.left=f.left;e.top=f.top}if(this.options.custom&&this.options.custom.refreshContainers){this.options.custom.refreshContainers.call(this)}else{for(var d=this.containers.length-1;d>=0;d--){var f=this.containers[d].element.offset();this.containers[d].containerCache.left=f.left;this.containers[d].containerCache.top=f.top;this.containers[d].containerCache.width=this.containers[d].element.outerWidth();this.containers[d].containerCache.height=this.containers[d].element.outerHeight()}}},_createPlaceholder:function(d){var b=d||this,e=b.options;if(!e.placeholder||e.placeholder.constructor==String){var c=e.placeholder;e.placeholder={element:function(){var f=a(document.createElement(b.currentItem[0].nodeName)).addClass(c||b.currentItem[0].className+" ui-sortable-placeholder").removeClass("ui-sortable-helper")[0];if(!c){f.style.visibility="hidden"}return f},update:function(f,g){if(c&&!e.forcePlaceholderSize){return}if(!g.height()){g.height(b.currentItem.innerHeight()-parseInt(b.currentItem.css("paddingTop")||0,10)-parseInt(b.currentItem.css("paddingBottom")||0,10))}if(!g.width()){g.width(b.currentItem.innerWidth()-parseInt(b.currentItem.css("paddingLeft")||0,10)-parseInt(b.currentItem.css("paddingRight")||0,10))}}}}b.placeholder=a(e.placeholder.element.call(b.element,b.currentItem));b.currentItem.after(b.placeholder);e.placeholder.update(b,b.placeholder)},_contactContainers:function(d){for(var c=this.containers.length-1;c>=0;c--){if(this._intersectsWith(this.containers[c].containerCache)){if(!this.containers[c].containerCache.over){if(this.currentContainer!=this.containers[c]){var h=10000;var g=null;var e=this.positionAbs[this.containers[c].floating?"left":"top"];for(var b=this.items.length-1;b>=0;b--){if(!a.ui.contains(this.containers[c].element[0],this.items[b].item[0])){continue}var f=this.items[b][this.containers[c].floating?"left":"top"];if(Math.abs(f-e)this.containment[2]){d=this.containment[2]+this.offset.click.left}if(e.pageY-this.offset.click.top>this.containment[3]){c=this.containment[3]+this.offset.click.top}}if(h.grid){var g=this.originalPageY+Math.round((c-this.originalPageY)/h.grid[1])*h.grid[1];c=this.containment?(!(g-this.offset.click.topthis.containment[3])?g:(!(g-this.offset.click.topthis.containment[2])?f:(!(f-this.offset.click.left=0;c--){if(a.ui.contains(this.containers[c].element[0],this.currentItem[0])&&!e){f.push((function(g){return function(h){g._trigger("receive",h,this._uiHash(this))}}).call(this,this.containers[c]));f.push((function(g){return function(h){g._trigger("update",h,this._uiHash(this))}}).call(this,this.containers[c]))}}}for(var c=this.containers.length-1;c>=0;c--){if(!e){f.push((function(g){return function(h){g._trigger("deactivate",h,this._uiHash(this))}}).call(this,this.containers[c]))}if(this.containers[c].containerCache.over){f.push((function(g){return function(h){g._trigger("out",h,this._uiHash(this))}}).call(this,this.containers[c]));this.containers[c].containerCache.over=0}}if(this._storedCursor){a("body").css("cursor",this._storedCursor)}if(this._storedOpacity){this.helper.css("opacity",this._storedOpacity)}if(this._storedZIndex){this.helper.css("zIndex",this._storedZIndex=="auto"?"":this._storedZIndex)}this.dragging=false;if(this.cancelHelperRemoval){if(!e){this._trigger("beforeStop",d,this._uiHash());for(var c=0;c *",opacity:false,placeholder:false,revert:false,scroll:true,scrollSensitivity:20,scrollSpeed:20,scope:"default",tolerance:"intersect",zIndex:1000}})})(jQuery);;/* + * jQuery UI Effects 1.7.2 + * + * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about) + * Dual licensed under the MIT (MIT-LICENSE.txt) + * and GPL (GPL-LICENSE.txt) licenses. + * + * http://docs.jquery.com/UI/Effects/ + */ +jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h').appendTo(document.body).addClass(b.options.className).css({top:d.top,left:d.left,height:f.innerHeight(),width:f.innerWidth(),position:"absolute"}).animate(g,b.duration,b.options.easing,function(){c.remove();(b.callback&&b.callback.apply(f[0],arguments));f.dequeue()})})}})(jQuery);; \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.alerts/images/help.gif b/spec/test_app/public/javascripts/jquery.alerts/images/help.gif new file mode 100755 index 0000000000000000000000000000000000000000..3b514253179abc826410a1c983b15d1a3239c95d GIT binary patch literal 1582 zcmV+}2GRLPNk%w1VITk?0QUd@a-QcgY19By)8y*(0Y$ncH=K#G^kS3d07=4csQ(&X z(dz8=8bqk<@%PQv>NrNC3roHrT+OS`|3i4w09o7{SPmH8rU=6$U5 zMPst`_4yGqq#iGHmg0uan%>SCf`vOS5jJNqidEQZl;Q%?Y ztGwPVWyuXrz`n%cMU3+(aP}i%+HtEt+2HOraMl|! zn^S|*dwaXt;_(1P!4Xl&E^*#cknR8d^Zxtw2NsV%dfauD&`EvT|Ns5}|M^IL)&2eZ z|Nr#;`}hDvwp@+nTZYdCKdlf$yB{T!PHeVYT&yKu&^lVK4^GH5Jf0mZn*aa*|Nr~{ z|Nb|7=5&R@I(*{>K(26|>;O8fK863=8{ zH*(v0pxsQ4@ob^$S%AuJo!^$k{qXJR2qmB#Adiur&5NhlnWN8`sME;N=+58sB`cMp zrO{rc|7o4=ZlLf1JEyq5-e!)|T#)Vh`}lvW@sg6pXqV}l#{X)agfOd`FNMm5h<1R z`1ygA$yko*A^8LV00000EC2ui03ZM$000R804E6?NU)&6g9sBUT!?UuF@KD>Fkm2q z!zFwj7#?iJq22@@S~h55_HPCQF2sgYrUxLwtfsB5#$0uv--5?~qiV1-5pTm;?9 zkt9eP1Jck)lePn0x^qP2_*m#bMwT2Bk|Y7Z%g>oByi`y#aR6F|5+0@^T)@Q}(I82% zoq_h*8ix=^CTXfneSym_Gtu3>Stvl1n990Tl%Yr?1YN*D1{$OaDGDeIp@SN|WJE=p(SxeMqJTgbuc)DeA;=bL0}wDk5YHm25LC$&^XQ^MwZWEgj2?uf0cEn_ zCi2b?bR2|ADO8*?M6h_0SO;rBs7H>0hFMCu{v1e4GuPt07Nq|WOB#I(=6nS9Hm&|$|?kq@Wd0FeA`SS z5WFJ_AKYkkfe0R)fQKtO;2;GA5J-W8Jn{U13@9s2vc?OM{E$KfAAF!d1@R~X%p!Cw g7q&nRgi*u;1&ASrB#|@=^1?cE2QK*F1O)^DJ1*7%H2?qr literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/jquery.alerts/images/important.gif b/spec/test_app/public/javascripts/jquery.alerts/images/important.gif new file mode 100755 index 0000000000000000000000000000000000000000..41d49438fd08230095c699b2d6f80593f3aa8667 GIT binary patch literal 1492 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/jquery.alerts/images/title.gif b/spec/test_app/public/javascripts/jquery.alerts/images/title.gif new file mode 100755 index 0000000000000000000000000000000000000000..f92b59665df2fd0d1c5e798af0945d14daa880bc GIT binary patch literal 317 zcmXw!J4?e*0EI8wN-32h7TQhgQjvln@ljoL@C8l|R^8kj6#5fHry?#Er!G$Z0e^zs zG`(qJ;%%Db=Jw|1)uw4iH`{{Wa5x+e2hQQ~!B*)i4zfT7Ac~^laMaX1K}04b%WX}Ye94MPwF)JDW42FALk8HT|avmJZ1Lc3i`yOJcip7+J`vMh_D zG|8yn^VidsEfmtRdOgm? IU-!VyACo}9@&Et; literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.css b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.css new file mode 100755 index 0000000..5df7792 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.css @@ -0,0 +1,57 @@ +#popup_container { + font-family: Arial, sans-serif; + font-size: 12px; + min-width: 300px; /* Dialog will be no smaller than this */ + max-width: 600px; /* Dialog will wrap after this width */ + background: #FFF; + border: solid 5px #999; + color: #000; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; +} + +#popup_title { + font-size: 14px; + font-weight: bold; + text-align: center; + line-height: 1.75em; + color: #666; + background: #CCC url(images/title.gif) top repeat-x; + border: solid 1px #FFF; + border-bottom: solid 1px #999; + cursor: default; + padding: 0em; + margin: 0em; +} + +#popup_content { + background: 16px 16px no-repeat url(images/info.gif); + padding: 1em 1.75em; + margin: 0em; +} + +#popup_content.alert { + background-image: url(images/info.gif); +} + +#popup_content.confirm { + background-image: url(images/important.gif); +} + +#popup_content.prompt { + background-image: url(images/help.gif); +} + +#popup_message { + padding-left: 48px; +} + +#popup_panel { + text-align: center; + margin: 1em 0em 0em 1em; +} + +#popup_prompt { + margin: .5em 0em; +} \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.js b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.js new file mode 100755 index 0000000..80b1c85 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.js @@ -0,0 +1,235 @@ +// jQuery Alert Dialogs Plugin +// +// Version 1.1 +// +// Cory S.N. LaViska +// A Beautiful Site (http://abeautifulsite.net/) +// 14 May 2009 +// +// Visit http://abeautifulsite.net/notebook/87 for more information +// +// Usage: +// jAlert( message, [title, callback] ) +// jConfirm( message, [title, callback] ) +// jPrompt( message, [value, title, callback] ) +// +// History: +// +// 1.00 - Released (29 December 2008) +// +// 1.01 - Fixed bug where unbinding would destroy all resize events +// +// License: +// +// This plugin is dual-licensed under the GNU General Public License and the MIT License and +// is copyright 2008 A Beautiful Site, LLC. +// +(function($) { + + $.alerts = { + + // These properties can be read/written by accessing $.alerts.propertyName from your scripts at any time + + verticalOffset: -75, // vertical offset of the dialog from center screen, in pixels + horizontalOffset: 0, // horizontal offset of the dialog from center screen, in pixels/ + repositionOnResize: true, // re-centers the dialog on window resize + overlayOpacity: .01, // transparency level of overlay + overlayColor: '#FFF', // base color of overlay + draggable: true, // make the dialogs draggable (requires UI Draggables plugin) + okButton: ' OK ', // text for the OK button + cancelButton: ' Cancel ', // text for the Cancel button + dialogClass: null, // if specified, this class will be applied to all dialogs + + // Public methods + + alert: function(message, title, callback) { + if( title == null ) title = 'Alert'; + $.alerts._show(title, message, null, 'alert', function(result) { + if( callback ) callback(result); + }); + }, + + confirm: function(message, title, callback) { + if( title == null ) title = 'Confirm'; + $.alerts._show(title, message, null, 'confirm', function(result) { + if( callback ) callback(result); + }); + }, + + prompt: function(message, value, title, callback) { + if( title == null ) title = 'Prompt'; + $.alerts._show(title, message, value, 'prompt', function(result) { + if( callback ) callback(result); + }); + }, + + // Private methods + + _show: function(title, msg, value, type, callback) { + + $.alerts._hide(); + $.alerts._overlay('show'); + + $("BODY").append( + ''); + + if( $.alerts.dialogClass ) $("#popup_container").addClass($.alerts.dialogClass); + + // IE6 Fix + var pos = ($.browser.msie && parseInt($.browser.version) <= 6 ) ? 'absolute' : 'fixed'; + + $("#popup_container").css({ + position: pos, + zIndex: 99999, + padding: 0, + margin: 0 + }); + + $("#popup_title").text(title); + $("#popup_content").addClass(type); + $("#popup_message").text(msg); + $("#popup_message").html( $("#popup_message").text().replace(/\n/g, '
') ); + + $("#popup_container").css({ + minWidth: $("#popup_container").outerWidth(), + maxWidth: $("#popup_container").outerWidth() + }); + + $.alerts._reposition(); + $.alerts._maintainPosition(true); + + switch( type ) { + case 'alert': + $("#popup_message").after(''); + $("#popup_ok").click( function() { + $.alerts._hide(); + callback(true); + }); + $("#popup_ok").focus().keypress( function(e) { + if( e.keyCode == 13 || e.keyCode == 27 ) $("#popup_ok").trigger('click'); + }); + break; + case 'confirm': + $("#popup_message").after(''); + $("#popup_ok").click( function() { + $.alerts._hide(); + if( callback ) callback(true); + }); + $("#popup_cancel").click( function() { + $.alerts._hide(); + if( callback ) callback(false); + }); + $("#popup_ok").focus(); + $("#popup_ok, #popup_cancel").keypress( function(e) { + if( e.keyCode == 13 ) $("#popup_ok").trigger('click'); + if( e.keyCode == 27 ) $("#popup_cancel").trigger('click'); + }); + break; + case 'prompt': + $("#popup_message").append('
').after(''); + $("#popup_prompt").width( $("#popup_message").width() ); + $("#popup_ok").click( function() { + var val = $("#popup_prompt").val(); + $.alerts._hide(); + if( callback ) callback( val ); + }); + $("#popup_cancel").click( function() { + $.alerts._hide(); + if( callback ) callback( null ); + }); + $("#popup_prompt, #popup_ok, #popup_cancel").keypress( function(e) { + if( e.keyCode == 13 ) $("#popup_ok").trigger('click'); + if( e.keyCode == 27 ) $("#popup_cancel").trigger('click'); + }); + if( value ) $("#popup_prompt").val(value); + $("#popup_prompt").focus().select(); + break; + } + + // Make draggable + if( $.alerts.draggable ) { + try { + $("#popup_container").draggable({ handle: $("#popup_title") }); + $("#popup_title").css({ cursor: 'move' }); + } catch(e) { /* requires jQuery UI draggables */ } + } + }, + + _hide: function() { + $("#popup_container").remove(); + $.alerts._overlay('hide'); + $.alerts._maintainPosition(false); + }, + + _overlay: function(status) { + switch( status ) { + case 'show': + $.alerts._overlay('hide'); + $("BODY").append(''); + $("#popup_overlay").css({ + position: 'absolute', + zIndex: 99998, + top: '0px', + left: '0px', + width: '100%', + height: $(document).height(), + background: $.alerts.overlayColor, + opacity: $.alerts.overlayOpacity + }); + break; + case 'hide': + $("#popup_overlay").remove(); + break; + } + }, + + _reposition: function() { + var top = (($(window).height() / 2) - ($("#popup_container").outerHeight() / 2)) + $.alerts.verticalOffset; + var left = (($(window).width() / 2) - ($("#popup_container").outerWidth() / 2)) + $.alerts.horizontalOffset; + if( top < 0 ) top = 0; + if( left < 0 ) left = 0; + + // IE6 fix + if( $.browser.msie && parseInt($.browser.version) <= 6 ) top = top + $(window).scrollTop(); + + $("#popup_container").css({ + top: top + 'px', + left: left + 'px' + }); + $("#popup_overlay").height( $(document).height() ); + }, + + _maintainPosition: function(status) { + if( $.alerts.repositionOnResize ) { + switch(status) { + case true: + $(window).bind('resize', $.alerts._reposition); + break; + case false: + $(window).unbind('resize', $.alerts._reposition); + break; + } + } + } + + } + + // Shortuct functions + jAlert = function(message, title, callback) { + $.alerts.alert(message, title, callback); + } + + jConfirm = function(message, title, callback) { + $.alerts.confirm(message, title, callback); + }; + + jPrompt = function(message, value, title, callback) { + $.alerts.prompt(message, value, title, callback); + }; + +})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.spree.css b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.spree.css new file mode 100644 index 0000000..15913c0 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.alerts/jquery.alerts.spree.css @@ -0,0 +1,30 @@ +/* Spree Custom dialog styles */ +#popup_container.spree { + + color: #fff; + background: #005294; + border-color: #113F66; +} + +#popup_container.spree #popup_title { + color: #FFF; + font-weight: normal; + text-align: left; + background: #76A5CC; + border: solid 1px #005294; + padding-left: 1em; +} + +#popup_container.spree #popup_content { + background: none; +} + +#popup_container.spree #popup_message { + padding-left: 0em; +} + +#popup_container.spree INPUT[type='button'] { + border: outset 2px #76A5CC; + color: #fff; + background: #3778AE; +} \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.autocomplete.min.js b/spec/test_app/public/javascripts/jquery.autocomplete.min.js new file mode 100644 index 0000000..40ce05e --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.autocomplete.min.js @@ -0,0 +1,13 @@ +/* + * jQuery Autocomplete plugin 1.1 + * + * Copyright (c) 2009 Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Revision: $Id: jquery.autocomplete.js 15 2009-08-22 10:30:27Z joern.zaefferer $ + */;(function($){$.fn.extend({autocomplete:function(urlOrData,options){var isUrl=typeof urlOrData=="string";options=$.extend({},$.Autocompleter.defaults,{url:isUrl?urlOrData:null,data:isUrl?null:urlOrData,delay:isUrl?$.Autocompleter.defaults.delay:10,max:options&&!options.scroll?10:150},options);options.highlight=options.highlight||function(value){return value;};options.formatMatch=options.formatMatch||options.formatItem;return this.each(function(){new $.Autocompleter(this,options);});},result:function(handler){return this.bind("result",handler);},search:function(handler){return this.trigger("search",[handler]);},flushCache:function(){return this.trigger("flushCache");},setOptions:function(options){return this.trigger("setOptions",[options]);},unautocomplete:function(){return this.trigger("unautocomplete");}});$.Autocompleter=function(input,options){var KEY={UP:38,DOWN:40,DEL:46,TAB:9,RETURN:13,ESC:27,COMMA:188,PAGEUP:33,PAGEDOWN:34,BACKSPACE:8};var $input=$(input).attr("autocomplete","off").addClass(options.inputClass);var timeout;var previousValue="";var cache=$.Autocompleter.Cache(options);var hasFocus=0;var lastKeyPressCode;var config={mouseDownOnSelect:false};var select=$.Autocompleter.Select(options,input,selectCurrent,config);var blockSubmit;$.browser.opera&&$(input.form).bind("submit.autocomplete",function(){if(blockSubmit){blockSubmit=false;return false;}});$input.bind(($.browser.opera?"keypress":"keydown")+".autocomplete",function(event){hasFocus=1;lastKeyPressCode=event.keyCode;switch(event.keyCode){case KEY.UP:event.preventDefault();if(select.visible()){select.prev();}else{onChange(0,true);}break;case KEY.DOWN:event.preventDefault();if(select.visible()){select.next();}else{onChange(0,true);}break;case KEY.PAGEUP:event.preventDefault();if(select.visible()){select.pageUp();}else{onChange(0,true);}break;case KEY.PAGEDOWN:event.preventDefault();if(select.visible()){select.pageDown();}else{onChange(0,true);}break;case options.multiple&&$.trim(options.multipleSeparator)==","&&KEY.COMMA:case KEY.TAB:case KEY.RETURN:if(selectCurrent()){event.preventDefault();blockSubmit=true;return false;}break;case KEY.ESC:select.hide();break;default:clearTimeout(timeout);timeout=setTimeout(onChange,options.delay);break;}}).focus(function(){hasFocus++;}).blur(function(){hasFocus=0;if(!config.mouseDownOnSelect){hideResults();}}).click(function(){if(hasFocus++>1&&!select.visible()){onChange(0,true);}}).bind("search",function(){var fn=(arguments.length>1)?arguments[1]:null;function findValueCallback(q,data){var result;if(data&&data.length){for(var i=0;i1){var seperator=options.multipleSeparator.length;var cursorAt=$(input).selection().start;var wordAt,progress=0;$.each(words,function(i,word){progress+=word.length;if(cursorAt<=progress){wordAt=i;return false;}progress+=seperator;});words[wordAt]=v;v=words.join(options.multipleSeparator);}v+=options.multipleSeparator;}$input.val(v);hideResultsNow();$input.trigger("result",[selected.data,selected.value]);return true;}function onChange(crap,skipPrevCheck){if(lastKeyPressCode==KEY.DEL){select.hide();return;}var currentValue=$input.val();if(!skipPrevCheck&¤tValue==previousValue)return;previousValue=currentValue;currentValue=lastWord(currentValue);if(currentValue.length>=options.minChars){$input.addClass(options.loadingClass);if(!options.matchCase)currentValue=currentValue.toLowerCase();request(currentValue,receiveData,hideResultsNow);}else{stopLoading();select.hide();}};function trimWords(value){if(!value)return[""];if(!options.multiple)return[$.trim(value)];return $.map(value.split(options.multipleSeparator),function(word){return $.trim(value).length?$.trim(word):null;});}function lastWord(value){if(!options.multiple)return value;var words=trimWords(value);if(words.length==1)return words[0];var cursorAt=$(input).selection().start;if(cursorAt==value.length){words=trimWords(value)}else{words=trimWords(value.replace(value.substring(cursorAt),""));}return words[words.length-1];}function autoFill(q,sValue){if(options.autoFill&&(lastWord($input.val()).toLowerCase()==q.toLowerCase())&&lastKeyPressCode!=KEY.BACKSPACE){$input.val($input.val()+sValue.substring(lastWord(previousValue).length));$(input).selection(previousValue.length,previousValue.length+sValue.length);}};function hideResults(){clearTimeout(timeout);timeout=setTimeout(hideResultsNow,200);};function hideResultsNow(){var wasVisible=select.visible();select.hide();clearTimeout(timeout);stopLoading();if(options.mustMatch){$input.search(function(result){if(!result){if(options.multiple){var words=trimWords($input.val()).slice(0,-1);$input.val(words.join(options.multipleSeparator)+(words.length?options.multipleSeparator:""));}else{$input.val("");$input.trigger("result",null);}}});}};function receiveData(q,data){if(data&&data.length&&hasFocus){stopLoading();select.display(data,q);autoFill(q,data[0].value);select.show();}else{hideResultsNow();}};function request(term,success,failure){if(!options.matchCase)term=term.toLowerCase();var data=cache.load(term);if(data&&data.length){success(term,data);}else if((typeof options.url=="string")&&(options.url.length>0)){var extraParams={timestamp:+new Date()};$.each(options.extraParams,function(key,param){extraParams[key]=typeof param=="function"?param():param;});$.ajax({mode:"abort",port:"autocomplete"+input.name,dataType:options.dataType,url:options.url,data:$.extend({q:lastWord(term),limit:options.max},extraParams),success:function(data){var parsed=options.parse&&options.parse(data)||parse(data);cache.add(term,parsed);success(term,parsed);}});}else{select.emptyList();failure(term);}};function parse(data){var parsed=[];var rows=data.split("\n");for(var i=0;i]*)("+term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi,"\\$1")+")(?![^<>]*>)(?![^&;]+;)","gi"),"$1");},scroll:true,scrollHeight:180};$.Autocompleter.Cache=function(options){var data={};var length=0;function matchSubset(s,sub){if(!options.matchCase)s=s.toLowerCase();var i=s.indexOf(sub);if(options.matchContains=="word"){i=s.toLowerCase().search("\\b"+sub.toLowerCase());}if(i==-1)return false;return i==0||options.matchContains;};function add(q,value){if(length>options.cacheLength){flush();}if(!data[q]){length++;}data[q]=value;}function populate(){if(!options.data)return false;var stMatchSets={},nullData=0;if(!options.url)options.cacheLength=1;stMatchSets[""]=[];for(var i=0,ol=options.data.length;i0){var c=data[k];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub.push(x);}});}}return csub;}else +if(data[q]){return data[q];}else +if(options.matchSubset){for(var i=q.length-1;i>=options.minChars;i--){var c=data[q.substr(0,i)];if(c){var csub=[];$.each(c,function(i,x){if(matchSubset(x.value,q)){csub[csub.length]=x;}});return csub;}}}return null;}};};$.Autocompleter.Select=function(options,input,select,config){var CLASSES={ACTIVE:"ac_over"};var listItems,active=-1,data,term="",needsInit=true,element,list;function init(){if(!needsInit)return;element=$("
").hide().addClass(options.resultsClass).css("position","absolute").appendTo(document.body);list=$("
    ").appendTo(element).mouseover(function(event){if(target(event).nodeName&&target(event).nodeName.toUpperCase()=='LI'){active=$("li",list).removeClass(CLASSES.ACTIVE).index(target(event));$(target(event)).addClass(CLASSES.ACTIVE);}}).click(function(event){$(target(event)).addClass(CLASSES.ACTIVE);select();input.focus();return false;}).mousedown(function(){config.mouseDownOnSelect=true;}).mouseup(function(){config.mouseDownOnSelect=false;});if(options.width>0)element.css("width",options.width);needsInit=false;}function target(event){var element=event.target;while(element&&element.tagName!="LI")element=element.parentNode;if(!element)return[];return element;}function moveSelect(step){listItems.slice(active,active+1).removeClass(CLASSES.ACTIVE);movePosition(step);var activeItem=listItems.slice(active,active+1).addClass(CLASSES.ACTIVE);if(options.scroll){var offset=0;listItems.slice(0,active).each(function(){offset+=this.offsetHeight;});if((offset+activeItem[0].offsetHeight-list.scrollTop())>list[0].clientHeight){list.scrollTop(offset+activeItem[0].offsetHeight-list.innerHeight());}else if(offset=listItems.size()){active=0;}}function limitNumberOfItems(available){return options.max&&options.max").html(options.highlight(formatted,term)).addClass(i%2==0?"ac_even":"ac_odd").appendTo(list)[0];$.data(li,"ac_data",data[i]);}listItems=list.find("li");if(options.selectFirst){listItems.slice(0,1).addClass(CLASSES.ACTIVE);active=0;}if($.fn.bgiframe)list.bgiframe();}return{display:function(d,q){init();data=d;term=q;fillList();},next:function(){moveSelect(1);},prev:function(){moveSelect(-1);},pageUp:function(){if(active!=0&&active-8<0){moveSelect(-active);}else{moveSelect(-8);}},pageDown:function(){if(active!=listItems.size()-1&&active+8>listItems.size()){moveSelect(listItems.size()-1-active);}else{moveSelect(8);}},hide:function(){element&&element.hide();listItems&&listItems.removeClass(CLASSES.ACTIVE);active=-1;},visible:function(){return element&&element.is(":visible");},current:function(){return this.visible()&&(listItems.filter("."+CLASSES.ACTIVE)[0]||options.selectFirst&&listItems[0]);},show:function(){var offset=$(input).offset();element.css({width:typeof options.width=="string"||options.width>0?options.width:$(input).width(),top:offset.top+input.offsetHeight,left:offset.left}).show();if(options.scroll){list.scrollTop(0);list.css({maxHeight:options.scrollHeight,overflow:'auto'});if($.browser.msie&&typeof document.body.style.maxHeight==="undefined"){var listHeight=0;listItems.each(function(){listHeight+=this.offsetHeight;});var scrollbarsVisible=listHeight>options.scrollHeight;list.css('height',scrollbarsVisible?options.scrollHeight:listHeight);if(!scrollbarsVisible){listItems.width(list.width()-parseInt(listItems.css("padding-left"))-parseInt(listItems.css("padding-right")));}}}},selected:function(){var selected=listItems&&listItems.filter("."+CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);return selected&&selected.length&&$.data(selected[0],"ac_data");},emptyList:function(){list&&list.empty();},unbind:function(){element&&element.remove();}};};$.fn.selection=function(start,end){if(start!==undefined){return this.each(function(){if(this.createTextRange){var selRange=this.createTextRange();if(end===undefined||start==end){selRange.move("character",start);selRange.select();}else{selRange.collapse(true);selRange.moveStart("character",start);selRange.moveEnd("character",end);selRange.select();}}else if(this.setSelectionRange){this.setSelectionRange(start,end);}else if(this.selectionStart){this.selectionStart=start;this.selectionEnd=end;}});}var field=this[0];if(field.createTextRange){var range=document.selection.createRange(),orig=field.value,teststring="<->",textLength=range.text.length;range.text=teststring;var caretAt=field.value.indexOf(teststring);field.value=orig;this.selection(caretAt,caretAt+textLength);return{start:caretAt,end:caretAt+textLength}}else if(field.selectionStart!==undefined){return{start:field.selectionStart,end:field.selectionEnd}}};})(jQuery); diff --git a/spec/test_app/public/javascripts/jquery.js b/spec/test_app/public/javascripts/jquery.js new file mode 100644 index 0000000..b1ae21d --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.js @@ -0,0 +1,19 @@ +/* + * jQuery JavaScript Library v1.3.2 + * http://jquery.com/ + * + * Copyright (c) 2009 John Resig + * Dual licensed under the MIT and GPL licenses. + * http://docs.jquery.com/License + * + * Date: 2009-02-19 17:34:21 -0500 (Thu, 19 Feb 2009) + * Revision: 6246 + */ +(function(){var l=this,g,y=l.jQuery,p=l.$,o=l.jQuery=l.$=function(E,F){return new o.fn.init(E,F)},D=/^[^<]*(<(.|\s)+>)[^>]*$|^#([\w-]+)$/,f=/^.[^:#\[\.,]*$/;o.fn=o.prototype={init:function(E,H){E=E||document;if(E.nodeType){this[0]=E;this.length=1;this.context=E;return this}if(typeof E==="string"){var G=D.exec(E);if(G&&(G[1]||!H)){if(G[1]){E=o.clean([G[1]],H)}else{var I=document.getElementById(G[3]);if(I&&I.id!=G[3]){return o().find(E)}var F=o(I||[]);F.context=document;F.selector=E;return F}}else{return o(H).find(E)}}else{if(o.isFunction(E)){return o(document).ready(E)}}if(E.selector&&E.context){this.selector=E.selector;this.context=E.context}return this.setArray(o.isArray(E)?E:o.makeArray(E))},selector:"",jquery:"1.3.2",size:function(){return this.length},get:function(E){return E===g?Array.prototype.slice.call(this):this[E]},pushStack:function(F,H,E){var G=o(F);G.prevObject=this;G.context=this.context;if(H==="find"){G.selector=this.selector+(this.selector?" ":"")+E}else{if(H){G.selector=this.selector+"."+H+"("+E+")"}}return G},setArray:function(E){this.length=0;Array.prototype.push.apply(this,E);return this},each:function(F,E){return o.each(this,F,E)},index:function(E){return o.inArray(E&&E.jquery?E[0]:E,this)},attr:function(F,H,G){var E=F;if(typeof F==="string"){if(H===g){return this[0]&&o[G||"attr"](this[0],F)}else{E={};E[F]=H}}return this.each(function(I){for(F in E){o.attr(G?this.style:this,F,o.prop(this,E[F],G,I,F))}})},css:function(E,F){if((E=="width"||E=="height")&&parseFloat(F)<0){F=g}return this.attr(E,F,"curCSS")},text:function(F){if(typeof F!=="object"&&F!=null){return this.empty().append((this[0]&&this[0].ownerDocument||document).createTextNode(F))}var E="";o.each(F||this,function(){o.each(this.childNodes,function(){if(this.nodeType!=8){E+=this.nodeType!=1?this.nodeValue:o.fn.text([this])}})});return E},wrapAll:function(E){if(this[0]){var F=o(E,this[0].ownerDocument).clone();if(this[0].parentNode){F.insertBefore(this[0])}F.map(function(){var G=this;while(G.firstChild){G=G.firstChild}return G}).append(this)}return this},wrapInner:function(E){return this.each(function(){o(this).contents().wrapAll(E)})},wrap:function(E){return this.each(function(){o(this).wrapAll(E)})},append:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.appendChild(E)}})},prepend:function(){return this.domManip(arguments,true,function(E){if(this.nodeType==1){this.insertBefore(E,this.firstChild)}})},before:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this)})},after:function(){return this.domManip(arguments,false,function(E){this.parentNode.insertBefore(E,this.nextSibling)})},end:function(){return this.prevObject||o([])},push:[].push,sort:[].sort,splice:[].splice,find:function(E){if(this.length===1){var F=this.pushStack([],"find",E);F.length=0;o.find(E,this[0],F);return F}else{return this.pushStack(o.unique(o.map(this,function(G){return o.find(E,G)})),"find",E)}},clone:function(G){var E=this.map(function(){if(!o.support.noCloneEvent&&!o.isXMLDoc(this)){var I=this.outerHTML;if(!I){var J=this.ownerDocument.createElement("div");J.appendChild(this.cloneNode(true));I=J.innerHTML}return o.clean([I.replace(/ jQuery\d+="(?:\d+|null)"/g,"").replace(/^\s*/,"")])[0]}else{return this.cloneNode(true)}});if(G===true){var H=this.find("*").andSelf(),F=0;E.find("*").andSelf().each(function(){if(this.nodeName!==H[F].nodeName){return}var I=o.data(H[F],"events");for(var K in I){for(var J in I[K]){o.event.add(this,K,I[K][J],I[K][J].data)}}F++})}return E},filter:function(E){return this.pushStack(o.isFunction(E)&&o.grep(this,function(G,F){return E.call(G,F)})||o.multiFilter(E,o.grep(this,function(F){return F.nodeType===1})),"filter",E)},closest:function(E){var G=o.expr.match.POS.test(E)?o(E):null,F=0;return this.map(function(){var H=this;while(H&&H.ownerDocument){if(G?G.index(H)>-1:o(H).is(E)){o.data(H,"closest",F);return H}H=H.parentNode;F++}})},not:function(E){if(typeof E==="string"){if(f.test(E)){return this.pushStack(o.multiFilter(E,this,true),"not",E)}else{E=o.multiFilter(E,this)}}var F=E.length&&E[E.length-1]!==g&&!E.nodeType;return this.filter(function(){return F?o.inArray(this,E)<0:this!=E})},add:function(E){return this.pushStack(o.unique(o.merge(this.get(),typeof E==="string"?o(E):o.makeArray(E))))},is:function(E){return !!E&&o.multiFilter(E,this).length>0},hasClass:function(E){return !!E&&this.is("."+E)},val:function(K){if(K===g){var E=this[0];if(E){if(o.nodeName(E,"option")){return(E.attributes.value||{}).specified?E.value:E.text}if(o.nodeName(E,"select")){var I=E.selectedIndex,L=[],M=E.options,H=E.type=="select-one";if(I<0){return null}for(var F=H?I:0,J=H?I+1:M.length;F=0||o.inArray(this.name,K)>=0)}else{if(o.nodeName(this,"select")){var N=o.makeArray(K);o("option",this).each(function(){this.selected=(o.inArray(this.value,N)>=0||o.inArray(this.text,N)>=0)});if(!N.length){this.selectedIndex=-1}}else{this.value=K}}})},html:function(E){return E===g?(this[0]?this[0].innerHTML.replace(/ jQuery\d+="(?:\d+|null)"/g,""):null):this.empty().append(E)},replaceWith:function(E){return this.after(E).remove()},eq:function(E){return this.slice(E,+E+1)},slice:function(){return this.pushStack(Array.prototype.slice.apply(this,arguments),"slice",Array.prototype.slice.call(arguments).join(","))},map:function(E){return this.pushStack(o.map(this,function(G,F){return E.call(G,F,G)}))},andSelf:function(){return this.add(this.prevObject)},domManip:function(J,M,L){if(this[0]){var I=(this[0].ownerDocument||this[0]).createDocumentFragment(),F=o.clean(J,(this[0].ownerDocument||this[0]),I),H=I.firstChild;if(H){for(var G=0,E=this.length;G1||G>0?I.cloneNode(true):I)}}if(F){o.each(F,z)}}return this;function K(N,O){return M&&o.nodeName(N,"table")&&o.nodeName(O,"tr")?(N.getElementsByTagName("tbody")[0]||N.appendChild(N.ownerDocument.createElement("tbody"))):N}}};o.fn.init.prototype=o.fn;function z(E,F){if(F.src){o.ajax({url:F.src,async:false,dataType:"script"})}else{o.globalEval(F.text||F.textContent||F.innerHTML||"")}if(F.parentNode){F.parentNode.removeChild(F)}}function e(){return +new Date}o.extend=o.fn.extend=function(){var J=arguments[0]||{},H=1,I=arguments.length,E=false,G;if(typeof J==="boolean"){E=J;J=arguments[1]||{};H=2}if(typeof J!=="object"&&!o.isFunction(J)){J={}}if(I==H){J=this;--H}for(;H-1}},swap:function(H,G,I){var E={};for(var F in G){E[F]=H.style[F];H.style[F]=G[F]}I.call(H);for(var F in G){H.style[F]=E[F]}},css:function(H,F,J,E){if(F=="width"||F=="height"){var L,G={position:"absolute",visibility:"hidden",display:"block"},K=F=="width"?["Left","Right"]:["Top","Bottom"];function I(){L=F=="width"?H.offsetWidth:H.offsetHeight;if(E==="border"){return}o.each(K,function(){if(!E){L-=parseFloat(o.curCSS(H,"padding"+this,true))||0}if(E==="margin"){L+=parseFloat(o.curCSS(H,"margin"+this,true))||0}else{L-=parseFloat(o.curCSS(H,"border"+this+"Width",true))||0}})}if(H.offsetWidth!==0){I()}else{o.swap(H,G,I)}return Math.max(0,Math.round(L))}return o.curCSS(H,F,J)},curCSS:function(I,F,G){var L,E=I.style;if(F=="opacity"&&!o.support.opacity){L=o.attr(E,"opacity");return L==""?"1":L}if(F.match(/float/i)){F=w}if(!G&&E&&E[F]){L=E[F]}else{if(q.getComputedStyle){if(F.match(/float/i)){F="float"}F=F.replace(/([A-Z])/g,"-$1").toLowerCase();var M=q.getComputedStyle(I,null);if(M){L=M.getPropertyValue(F)}if(F=="opacity"&&L==""){L="1"}}else{if(I.currentStyle){var J=F.replace(/\-(\w)/g,function(N,O){return O.toUpperCase()});L=I.currentStyle[F]||I.currentStyle[J];if(!/^\d+(px)?$/i.test(L)&&/^\d/.test(L)){var H=E.left,K=I.runtimeStyle.left;I.runtimeStyle.left=I.currentStyle.left;E.left=L||0;L=E.pixelLeft+"px";E.left=H;I.runtimeStyle.left=K}}}}return L},clean:function(F,K,I){K=K||document;if(typeof K.createElement==="undefined"){K=K.ownerDocument||K[0]&&K[0].ownerDocument||document}if(!I&&F.length===1&&typeof F[0]==="string"){var H=/^<(\w+)\s*\/?>$/.exec(F[0]);if(H){return[K.createElement(H[1])]}}var G=[],E=[],L=K.createElement("div");o.each(F,function(P,S){if(typeof S==="number"){S+=""}if(!S){return}if(typeof S==="string"){S=S.replace(/(<(\w+)[^>]*?)\/>/g,function(U,V,T){return T.match(/^(abbr|br|col|img|input|link|meta|param|hr|area|embed)$/i)?U:V+">"});var O=S.replace(/^\s+/,"").substring(0,10).toLowerCase();var Q=!O.indexOf("",""]||!O.indexOf("",""]||O.match(/^<(thead|tbody|tfoot|colg|cap)/)&&[1,"","
    "]||!O.indexOf("",""]||(!O.indexOf("",""]||!O.indexOf("",""]||!o.support.htmlSerialize&&[1,"div
    ","
    "]||[0,"",""];L.innerHTML=Q[1]+S+Q[2];while(Q[0]--){L=L.lastChild}if(!o.support.tbody){var R=/"&&!R?L.childNodes:[];for(var M=N.length-1;M>=0;--M){if(o.nodeName(N[M],"tbody")&&!N[M].childNodes.length){N[M].parentNode.removeChild(N[M])}}}if(!o.support.leadingWhitespace&&/^\s/.test(S)){L.insertBefore(K.createTextNode(S.match(/^\s*/)[0]),L.firstChild)}S=o.makeArray(L.childNodes)}if(S.nodeType){G.push(S)}else{G=o.merge(G,S)}});if(I){for(var J=0;G[J];J++){if(o.nodeName(G[J],"script")&&(!G[J].type||G[J].type.toLowerCase()==="text/javascript")){E.push(G[J].parentNode?G[J].parentNode.removeChild(G[J]):G[J])}else{if(G[J].nodeType===1){G.splice.apply(G,[J+1,0].concat(o.makeArray(G[J].getElementsByTagName("script"))))}I.appendChild(G[J])}}return E}return G},attr:function(J,G,K){if(!J||J.nodeType==3||J.nodeType==8){return g}var H=!o.isXMLDoc(J),L=K!==g;G=H&&o.props[G]||G;if(J.tagName){var F=/href|src|style/.test(G);if(G=="selected"&&J.parentNode){J.parentNode.selectedIndex}if(G in J&&H&&!F){if(L){if(G=="type"&&o.nodeName(J,"input")&&J.parentNode){throw"type property can't be changed"}J[G]=K}if(o.nodeName(J,"form")&&J.getAttributeNode(G)){return J.getAttributeNode(G).nodeValue}if(G=="tabIndex"){var I=J.getAttributeNode("tabIndex");return I&&I.specified?I.value:J.nodeName.match(/(button|input|object|select|textarea)/i)?0:J.nodeName.match(/^(a|area)$/i)&&J.href?0:g}return J[G]}if(!o.support.style&&H&&G=="style"){return o.attr(J.style,"cssText",K)}if(L){J.setAttribute(G,""+K)}var E=!o.support.hrefNormalized&&H&&F?J.getAttribute(G,2):J.getAttribute(G);return E===null?g:E}if(!o.support.opacity&&G=="opacity"){if(L){J.zoom=1;J.filter=(J.filter||"").replace(/alpha\([^)]*\)/,"")+(parseInt(K)+""=="NaN"?"":"alpha(opacity="+K*100+")")}return J.filter&&J.filter.indexOf("opacity=")>=0?(parseFloat(J.filter.match(/opacity=([^)]*)/)[1])/100)+"":""}G=G.replace(/-([a-z])/ig,function(M,N){return N.toUpperCase()});if(L){J[G]=K}return J[G]},trim:function(E){return(E||"").replace(/^\s+|\s+$/g,"")},makeArray:function(G){var E=[];if(G!=null){var F=G.length;if(F==null||typeof G==="string"||o.isFunction(G)||G.setInterval){E[0]=G}else{while(F){E[--F]=G[F]}}}return E},inArray:function(G,H){for(var E=0,F=H.length;E0?this.clone(true):this).get();o.fn[F].apply(o(L[K]),I);J=J.concat(I)}return this.pushStack(J,E,G)}});o.each({removeAttr:function(E){o.attr(this,E,"");if(this.nodeType==1){this.removeAttribute(E)}},addClass:function(E){o.className.add(this,E)},removeClass:function(E){o.className.remove(this,E)},toggleClass:function(F,E){if(typeof E!=="boolean"){E=!o.className.has(this,F)}o.className[E?"add":"remove"](this,F)},remove:function(E){if(!E||o.filter(E,[this]).length){o("*",this).add([this]).each(function(){o.event.remove(this);o.removeData(this)});if(this.parentNode){this.parentNode.removeChild(this)}}},empty:function(){o(this).children().remove();while(this.firstChild){this.removeChild(this.firstChild)}}},function(E,F){o.fn[E]=function(){return this.each(F,arguments)}});function j(E,F){return E[0]&&parseInt(o.curCSS(E[0],F,true),10)||0}var h="jQuery"+e(),v=0,A={};o.extend({cache:{},data:function(F,E,G){F=F==l?A:F;var H=F[h];if(!H){H=F[h]=++v}if(E&&!o.cache[H]){o.cache[H]={}}if(G!==g){o.cache[H][E]=G}return E?o.cache[H][E]:H},removeData:function(F,E){F=F==l?A:F;var H=F[h];if(E){if(o.cache[H]){delete o.cache[H][E];E="";for(E in o.cache[H]){break}if(!E){o.removeData(F)}}}else{try{delete F[h]}catch(G){if(F.removeAttribute){F.removeAttribute(h)}}delete o.cache[H]}},queue:function(F,E,H){if(F){E=(E||"fx")+"queue";var G=o.data(F,E);if(!G||o.isArray(H)){G=o.data(F,E,o.makeArray(H))}else{if(H){G.push(H)}}}return G},dequeue:function(H,G){var E=o.queue(H,G),F=E.shift();if(!G||G==="fx"){F=E[0]}if(F!==g){F.call(H)}}});o.fn.extend({data:function(E,G){var H=E.split(".");H[1]=H[1]?"."+H[1]:"";if(G===g){var F=this.triggerHandler("getData"+H[1]+"!",[H[0]]);if(F===g&&this.length){F=o.data(this[0],E)}return F===g&&H[1]?this.data(H[0]):F}else{return this.trigger("setData"+H[1]+"!",[H[0],G]).each(function(){o.data(this,E,G)})}},removeData:function(E){return this.each(function(){o.removeData(this,E)})},queue:function(E,F){if(typeof E!=="string"){F=E;E="fx"}if(F===g){return o.queue(this[0],E)}return this.each(function(){var G=o.queue(this,E,F);if(E=="fx"&&G.length==1){G[0].call(this)}})},dequeue:function(E){return this.each(function(){o.dequeue(this,E)})}}); +/* + * Sizzle CSS Selector Engine - v0.9.3 + * Copyright 2009, The Dojo Foundation + * Released under the MIT, BSD, and GPL Licenses. + * More information: http://sizzlejs.com/ + */ +(function(){var R=/((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?/g,L=0,H=Object.prototype.toString;var F=function(Y,U,ab,ac){ab=ab||[];U=U||document;if(U.nodeType!==1&&U.nodeType!==9){return[]}if(!Y||typeof Y!=="string"){return ab}var Z=[],W,af,ai,T,ad,V,X=true;R.lastIndex=0;while((W=R.exec(Y))!==null){Z.push(W[1]);if(W[2]){V=RegExp.rightContext;break}}if(Z.length>1&&M.exec(Y)){if(Z.length===2&&I.relative[Z[0]]){af=J(Z[0]+Z[1],U)}else{af=I.relative[Z[0]]?[U]:F(Z.shift(),U);while(Z.length){Y=Z.shift();if(I.relative[Y]){Y+=Z.shift()}af=J(Y,af)}}}else{var ae=ac?{expr:Z.pop(),set:E(ac)}:F.find(Z.pop(),Z.length===1&&U.parentNode?U.parentNode:U,Q(U));af=F.filter(ae.expr,ae.set);if(Z.length>0){ai=E(af)}else{X=false}while(Z.length){var ah=Z.pop(),ag=ah;if(!I.relative[ah]){ah=""}else{ag=Z.pop()}if(ag==null){ag=U}I.relative[ah](ai,ag,Q(U))}}if(!ai){ai=af}if(!ai){throw"Syntax error, unrecognized expression: "+(ah||Y)}if(H.call(ai)==="[object Array]"){if(!X){ab.push.apply(ab,ai)}else{if(U.nodeType===1){for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&(ai[aa]===true||ai[aa].nodeType===1&&K(U,ai[aa]))){ab.push(af[aa])}}}else{for(var aa=0;ai[aa]!=null;aa++){if(ai[aa]&&ai[aa].nodeType===1){ab.push(af[aa])}}}}}else{E(ai,ab)}if(V){F(V,U,ab,ac);if(G){hasDuplicate=false;ab.sort(G);if(hasDuplicate){for(var aa=1;aa":function(Z,U,aa){var X=typeof U==="string";if(X&&!/\W/.test(U)){U=aa?U:U.toUpperCase();for(var V=0,T=Z.length;V=0)){if(!V){T.push(Y)}}else{if(V){U[X]=false}}}}return false},ID:function(T){return T[1].replace(/\\/g,"")},TAG:function(U,T){for(var V=0;T[V]===false;V++){}return T[V]&&Q(T[V])?U[1]:U[1].toUpperCase()},CHILD:function(T){if(T[1]=="nth"){var U=/(-?)(\d*)n((?:\+|-)?\d*)/.exec(T[2]=="even"&&"2n"||T[2]=="odd"&&"2n+1"||!/\D/.test(T[2])&&"0n+"+T[2]||T[2]);T[2]=(U[1]+(U[2]||1))-0;T[3]=U[3]-0}T[0]=L++;return T},ATTR:function(X,U,V,T,Y,Z){var W=X[1].replace(/\\/g,"");if(!Z&&I.attrMap[W]){X[1]=I.attrMap[W]}if(X[2]==="~="){X[4]=" "+X[4]+" "}return X},PSEUDO:function(X,U,V,T,Y){if(X[1]==="not"){if(X[3].match(R).length>1||/^\w/.test(X[3])){X[3]=F(X[3],null,null,U)}else{var W=F.filter(X[3],U,V,true^Y);if(!V){T.push.apply(T,W)}return false}}else{if(I.match.POS.test(X[0])||I.match.CHILD.test(X[0])){return true}}return X},POS:function(T){T.unshift(true);return T}},filters:{enabled:function(T){return T.disabled===false&&T.type!=="hidden"},disabled:function(T){return T.disabled===true},checked:function(T){return T.checked===true},selected:function(T){T.parentNode.selectedIndex;return T.selected===true},parent:function(T){return !!T.firstChild},empty:function(T){return !T.firstChild},has:function(V,U,T){return !!F(T[3],V).length},header:function(T){return/h\d/i.test(T.nodeName)},text:function(T){return"text"===T.type},radio:function(T){return"radio"===T.type},checkbox:function(T){return"checkbox"===T.type},file:function(T){return"file"===T.type},password:function(T){return"password"===T.type},submit:function(T){return"submit"===T.type},image:function(T){return"image"===T.type},reset:function(T){return"reset"===T.type},button:function(T){return"button"===T.type||T.nodeName.toUpperCase()==="BUTTON"},input:function(T){return/input|select|textarea|button/i.test(T.nodeName)}},setFilters:{first:function(U,T){return T===0},last:function(V,U,T,W){return U===W.length-1},even:function(U,T){return T%2===0},odd:function(U,T){return T%2===1},lt:function(V,U,T){return UT[3]-0},nth:function(V,U,T){return T[3]-0==U},eq:function(V,U,T){return T[3]-0==U}},filter:{PSEUDO:function(Z,V,W,aa){var U=V[1],X=I.filters[U];if(X){return X(Z,W,V,aa)}else{if(U==="contains"){return(Z.textContent||Z.innerText||"").indexOf(V[3])>=0}else{if(U==="not"){var Y=V[3];for(var W=0,T=Y.length;W=0)}}},ID:function(U,T){return U.nodeType===1&&U.getAttribute("id")===T},TAG:function(U,T){return(T==="*"&&U.nodeType===1)||U.nodeName===T},CLASS:function(U,T){return(" "+(U.className||U.getAttribute("class"))+" ").indexOf(T)>-1},ATTR:function(Y,W){var V=W[1],T=I.attrHandle[V]?I.attrHandle[V](Y):Y[V]!=null?Y[V]:Y.getAttribute(V),Z=T+"",X=W[2],U=W[4];return T==null?X==="!=":X==="="?Z===U:X==="*="?Z.indexOf(U)>=0:X==="~="?(" "+Z+" ").indexOf(U)>=0:!U?Z&&T!==false:X==="!="?Z!=U:X==="^="?Z.indexOf(U)===0:X==="$="?Z.substr(Z.length-U.length)===U:X==="|="?Z===U||Z.substr(0,U.length+1)===U+"-":false},POS:function(X,U,V,Y){var T=U[2],W=I.setFilters[T];if(W){return W(X,V,U,Y)}}}};var M=I.match.POS;for(var O in I.match){I.match[O]=RegExp(I.match[O].source+/(?![^\[]*\])(?![^\(]*\))/.source)}var E=function(U,T){U=Array.prototype.slice.call(U);if(T){T.push.apply(T,U);return T}return U};try{Array.prototype.slice.call(document.documentElement.childNodes)}catch(N){E=function(X,W){var U=W||[];if(H.call(X)==="[object Array]"){Array.prototype.push.apply(U,X)}else{if(typeof X.length==="number"){for(var V=0,T=X.length;V";var T=document.documentElement;T.insertBefore(U,T.firstChild);if(!!document.getElementById(V)){I.find.ID=function(X,Y,Z){if(typeof Y.getElementById!=="undefined"&&!Z){var W=Y.getElementById(X[1]);return W?W.id===X[1]||typeof W.getAttributeNode!=="undefined"&&W.getAttributeNode("id").nodeValue===X[1]?[W]:g:[]}};I.filter.ID=function(Y,W){var X=typeof Y.getAttributeNode!=="undefined"&&Y.getAttributeNode("id");return Y.nodeType===1&&X&&X.nodeValue===W}}T.removeChild(U)})();(function(){var T=document.createElement("div");T.appendChild(document.createComment(""));if(T.getElementsByTagName("*").length>0){I.find.TAG=function(U,Y){var X=Y.getElementsByTagName(U[1]);if(U[1]==="*"){var W=[];for(var V=0;X[V];V++){if(X[V].nodeType===1){W.push(X[V])}}X=W}return X}}T.innerHTML="";if(T.firstChild&&typeof T.firstChild.getAttribute!=="undefined"&&T.firstChild.getAttribute("href")!=="#"){I.attrHandle.href=function(U){return U.getAttribute("href",2)}}})();if(document.querySelectorAll){(function(){var T=F,U=document.createElement("div");U.innerHTML="

    ";if(U.querySelectorAll&&U.querySelectorAll(".TEST").length===0){return}F=function(Y,X,V,W){X=X||document;if(!W&&X.nodeType===9&&!Q(X)){try{return E(X.querySelectorAll(Y),V)}catch(Z){}}return T(Y,X,V,W)};F.find=T.find;F.filter=T.filter;F.selectors=T.selectors;F.matches=T.matches})()}if(document.getElementsByClassName&&document.documentElement.getElementsByClassName){(function(){var T=document.createElement("div");T.innerHTML="
    ";if(T.getElementsByClassName("e").length===0){return}T.lastChild.className="e";if(T.getElementsByClassName("e").length===1){return}I.order.splice(1,0,"CLASS");I.find.CLASS=function(U,V,W){if(typeof V.getElementsByClassName!=="undefined"&&!W){return V.getElementsByClassName(U[1])}}})()}function P(U,Z,Y,ad,aa,ac){var ab=U=="previousSibling"&&!ac;for(var W=0,V=ad.length;W0){X=T;break}}}T=T[U]}ad[W]=X}}}var K=document.compareDocumentPosition?function(U,T){return U.compareDocumentPosition(T)&16}:function(U,T){return U!==T&&(U.contains?U.contains(T):true)};var Q=function(T){return T.nodeType===9&&T.documentElement.nodeName!=="HTML"||!!T.ownerDocument&&Q(T.ownerDocument)};var J=function(T,aa){var W=[],X="",Y,V=aa.nodeType?[aa]:aa;while((Y=I.match.PSEUDO.exec(T))){X+=Y[0];T=T.replace(I.match.PSEUDO,"")}T=I.relative[T]?T+"*":T;for(var Z=0,U=V.length;Z0||T.offsetHeight>0};F.selectors.filters.animated=function(T){return o.grep(o.timers,function(U){return T===U.elem}).length};o.multiFilter=function(V,T,U){if(U){V=":not("+V+")"}return F.matches(V,T)};o.dir=function(V,U){var T=[],W=V[U];while(W&&W!=document){if(W.nodeType==1){T.push(W)}W=W[U]}return T};o.nth=function(X,T,V,W){T=T||1;var U=0;for(;X;X=X[V]){if(X.nodeType==1&&++U==T){break}}return X};o.sibling=function(V,U){var T=[];for(;V;V=V.nextSibling){if(V.nodeType==1&&V!=U){T.push(V)}}return T};return;l.Sizzle=F})();o.event={add:function(I,F,H,K){if(I.nodeType==3||I.nodeType==8){return}if(I.setInterval&&I!=l){I=l}if(!H.guid){H.guid=this.guid++}if(K!==g){var G=H;H=this.proxy(G);H.data=K}var E=o.data(I,"events")||o.data(I,"events",{}),J=o.data(I,"handle")||o.data(I,"handle",function(){return typeof o!=="undefined"&&!o.event.triggered?o.event.handle.apply(arguments.callee.elem,arguments):g});J.elem=I;o.each(F.split(/\s+/),function(M,N){var O=N.split(".");N=O.shift();H.type=O.slice().sort().join(".");var L=E[N];if(o.event.specialAll[N]){o.event.specialAll[N].setup.call(I,K,O)}if(!L){L=E[N]={};if(!o.event.special[N]||o.event.special[N].setup.call(I,K,O)===false){if(I.addEventListener){I.addEventListener(N,J,false)}else{if(I.attachEvent){I.attachEvent("on"+N,J)}}}}L[H.guid]=H;o.event.global[N]=true});I=null},guid:1,global:{},remove:function(K,H,J){if(K.nodeType==3||K.nodeType==8){return}var G=o.data(K,"events"),F,E;if(G){if(H===g||(typeof H==="string"&&H.charAt(0)==".")){for(var I in G){this.remove(K,I+(H||""))}}else{if(H.type){J=H.handler;H=H.type}o.each(H.split(/\s+/),function(M,O){var Q=O.split(".");O=Q.shift();var N=RegExp("(^|\\.)"+Q.slice().sort().join(".*\\.")+"(\\.|$)");if(G[O]){if(J){delete G[O][J.guid]}else{for(var P in G[O]){if(N.test(G[O][P].type)){delete G[O][P]}}}if(o.event.specialAll[O]){o.event.specialAll[O].teardown.call(K,Q)}for(F in G[O]){break}if(!F){if(!o.event.special[O]||o.event.special[O].teardown.call(K,Q)===false){if(K.removeEventListener){K.removeEventListener(O,o.data(K,"handle"),false)}else{if(K.detachEvent){K.detachEvent("on"+O,o.data(K,"handle"))}}}F=null;delete G[O]}}})}for(F in G){break}if(!F){var L=o.data(K,"handle");if(L){L.elem=null}o.removeData(K,"events");o.removeData(K,"handle")}}},trigger:function(I,K,H,E){var G=I.type||I;if(!E){I=typeof I==="object"?I[h]?I:o.extend(o.Event(G),I):o.Event(G);if(G.indexOf("!")>=0){I.type=G=G.slice(0,-1);I.exclusive=true}if(!H){I.stopPropagation();if(this.global[G]){o.each(o.cache,function(){if(this.events&&this.events[G]){o.event.trigger(I,K,this.handle.elem)}})}}if(!H||H.nodeType==3||H.nodeType==8){return g}I.result=g;I.target=H;K=o.makeArray(K);K.unshift(I)}I.currentTarget=H;var J=o.data(H,"handle");if(J){J.apply(H,K)}if((!H[G]||(o.nodeName(H,"a")&&G=="click"))&&H["on"+G]&&H["on"+G].apply(H,K)===false){I.result=false}if(!E&&H[G]&&!I.isDefaultPrevented()&&!(o.nodeName(H,"a")&&G=="click")){this.triggered=true;try{H[G]()}catch(L){}}this.triggered=false;if(!I.isPropagationStopped()){var F=H.parentNode||H.ownerDocument;if(F){o.event.trigger(I,K,F,true)}}},handle:function(K){var J,E;K=arguments[0]=o.event.fix(K||l.event);K.currentTarget=this;var L=K.type.split(".");K.type=L.shift();J=!L.length&&!K.exclusive;var I=RegExp("(^|\\.)"+L.slice().sort().join(".*\\.")+"(\\.|$)");E=(o.data(this,"events")||{})[K.type];for(var G in E){var H=E[G];if(J||I.test(H.type)){K.handler=H;K.data=H.data;var F=H.apply(this,arguments);if(F!==g){K.result=F;if(F===false){K.preventDefault();K.stopPropagation()}}if(K.isImmediatePropagationStopped()){break}}}},props:"altKey attrChange attrName bubbles button cancelable charCode clientX clientY ctrlKey currentTarget data detail eventPhase fromElement handler keyCode metaKey newValue originalTarget pageX pageY prevValue relatedNode relatedTarget screenX screenY shiftKey srcElement target toElement view wheelDelta which".split(" "),fix:function(H){if(H[h]){return H}var F=H;H=o.Event(F);for(var G=this.props.length,J;G;){J=this.props[--G];H[J]=F[J]}if(!H.target){H.target=H.srcElement||document}if(H.target.nodeType==3){H.target=H.target.parentNode}if(!H.relatedTarget&&H.fromElement){H.relatedTarget=H.fromElement==H.target?H.toElement:H.fromElement}if(H.pageX==null&&H.clientX!=null){var I=document.documentElement,E=document.body;H.pageX=H.clientX+(I&&I.scrollLeft||E&&E.scrollLeft||0)-(I.clientLeft||0);H.pageY=H.clientY+(I&&I.scrollTop||E&&E.scrollTop||0)-(I.clientTop||0)}if(!H.which&&((H.charCode||H.charCode===0)?H.charCode:H.keyCode)){H.which=H.charCode||H.keyCode}if(!H.metaKey&&H.ctrlKey){H.metaKey=H.ctrlKey}if(!H.which&&H.button){H.which=(H.button&1?1:(H.button&2?3:(H.button&4?2:0)))}return H},proxy:function(F,E){E=E||function(){return F.apply(this,arguments)};E.guid=F.guid=F.guid||E.guid||this.guid++;return E},special:{ready:{setup:B,teardown:function(){}}},specialAll:{live:{setup:function(E,F){o.event.add(this,F[0],c)},teardown:function(G){if(G.length){var E=0,F=RegExp("(^|\\.)"+G[0]+"(\\.|$)");o.each((o.data(this,"events").live||{}),function(){if(F.test(this.type)){E++}});if(E<1){o.event.remove(this,G[0],c)}}}}}};o.Event=function(E){if(!this.preventDefault){return new o.Event(E)}if(E&&E.type){this.originalEvent=E;this.type=E.type}else{this.type=E}this.timeStamp=e();this[h]=true};function k(){return false}function u(){return true}o.Event.prototype={preventDefault:function(){this.isDefaultPrevented=u;var E=this.originalEvent;if(!E){return}if(E.preventDefault){E.preventDefault()}E.returnValue=false},stopPropagation:function(){this.isPropagationStopped=u;var E=this.originalEvent;if(!E){return}if(E.stopPropagation){E.stopPropagation()}E.cancelBubble=true},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=u;this.stopPropagation()},isDefaultPrevented:k,isPropagationStopped:k,isImmediatePropagationStopped:k};var a=function(F){var E=F.relatedTarget;while(E&&E!=this){try{E=E.parentNode}catch(G){E=this}}if(E!=this){F.type=F.data;o.event.handle.apply(this,arguments)}};o.each({mouseover:"mouseenter",mouseout:"mouseleave"},function(F,E){o.event.special[E]={setup:function(){o.event.add(this,F,a,E)},teardown:function(){o.event.remove(this,F,a)}}});o.fn.extend({bind:function(F,G,E){return F=="unload"?this.one(F,G,E):this.each(function(){o.event.add(this,F,E||G,E&&G)})},one:function(G,H,F){var E=o.event.proxy(F||H,function(I){o(this).unbind(I,E);return(F||H).apply(this,arguments)});return this.each(function(){o.event.add(this,G,E,F&&H)})},unbind:function(F,E){return this.each(function(){o.event.remove(this,F,E)})},trigger:function(E,F){return this.each(function(){o.event.trigger(E,F,this)})},triggerHandler:function(E,G){if(this[0]){var F=o.Event(E);F.preventDefault();F.stopPropagation();o.event.trigger(F,G,this[0]);return F.result}},toggle:function(G){var E=arguments,F=1;while(F=0){var E=G.slice(I,G.length);G=G.slice(0,I)}var H="GET";if(J){if(o.isFunction(J)){K=J;J=null}else{if(typeof J==="object"){J=o.param(J);H="POST"}}}var F=this;o.ajax({url:G,type:H,dataType:"html",data:J,complete:function(M,L){if(L=="success"||L=="notmodified"){F.html(E?o("
    ").append(M.responseText.replace(//g,"")).find(E):M.responseText)}if(K){F.each(K,[M.responseText,L,M])}}});return this},serialize:function(){return o.param(this.serializeArray())},serializeArray:function(){return this.map(function(){return this.elements?o.makeArray(this.elements):this}).filter(function(){return this.name&&!this.disabled&&(this.checked||/select|textarea/i.test(this.nodeName)||/text|hidden|password|search/i.test(this.type))}).map(function(E,F){var G=o(this).val();return G==null?null:o.isArray(G)?o.map(G,function(I,H){return{name:F.name,value:I}}):{name:F.name,value:G}}).get()}});o.each("ajaxStart,ajaxStop,ajaxComplete,ajaxError,ajaxSuccess,ajaxSend".split(","),function(E,F){o.fn[F]=function(G){return this.bind(F,G)}});var r=e();o.extend({get:function(E,G,H,F){if(o.isFunction(G)){H=G;G=null}return o.ajax({type:"GET",url:E,data:G,success:H,dataType:F})},getScript:function(E,F){return o.get(E,null,F,"script")},getJSON:function(E,F,G){return o.get(E,F,G,"json")},post:function(E,G,H,F){if(o.isFunction(G)){H=G;G={}}return o.ajax({type:"POST",url:E,data:G,success:H,dataType:F})},ajaxSetup:function(E){o.extend(o.ajaxSettings,E)},ajaxSettings:{url:location.href,global:true,type:"GET",contentType:"application/x-www-form-urlencoded",processData:true,async:true,xhr:function(){return l.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):new XMLHttpRequest()},accepts:{xml:"application/xml, text/xml",html:"text/html",script:"text/javascript, application/javascript",json:"application/json, text/javascript",text:"text/plain",_default:"*/*"}},lastModified:{},ajax:function(M){M=o.extend(true,M,o.extend(true,{},o.ajaxSettings,M));var W,F=/=\?(&|$)/g,R,V,G=M.type.toUpperCase();if(M.data&&M.processData&&typeof M.data!=="string"){M.data=o.param(M.data)}if(M.dataType=="jsonp"){if(G=="GET"){if(!M.url.match(F)){M.url+=(M.url.match(/\?/)?"&":"?")+(M.jsonp||"callback")+"=?"}}else{if(!M.data||!M.data.match(F)){M.data=(M.data?M.data+"&":"")+(M.jsonp||"callback")+"=?"}}M.dataType="json"}if(M.dataType=="json"&&(M.data&&M.data.match(F)||M.url.match(F))){W="jsonp"+r++;if(M.data){M.data=(M.data+"").replace(F,"="+W+"$1")}M.url=M.url.replace(F,"="+W+"$1");M.dataType="script";l[W]=function(X){V=X;I();L();l[W]=g;try{delete l[W]}catch(Y){}if(H){H.removeChild(T)}}}if(M.dataType=="script"&&M.cache==null){M.cache=false}if(M.cache===false&&G=="GET"){var E=e();var U=M.url.replace(/(\?|&)_=.*?(&|$)/,"$1_="+E+"$2");M.url=U+((U==M.url)?(M.url.match(/\?/)?"&":"?")+"_="+E:"")}if(M.data&&G=="GET"){M.url+=(M.url.match(/\?/)?"&":"?")+M.data;M.data=null}if(M.global&&!o.active++){o.event.trigger("ajaxStart")}var Q=/^(\w+:)?\/\/([^\/?#]+)/.exec(M.url);if(M.dataType=="script"&&G=="GET"&&Q&&(Q[1]&&Q[1]!=location.protocol||Q[2]!=location.host)){var H=document.getElementsByTagName("head")[0];var T=document.createElement("script");T.src=M.url;if(M.scriptCharset){T.charset=M.scriptCharset}if(!W){var O=false;T.onload=T.onreadystatechange=function(){if(!O&&(!this.readyState||this.readyState=="loaded"||this.readyState=="complete")){O=true;I();L();T.onload=T.onreadystatechange=null;H.removeChild(T)}}}H.appendChild(T);return g}var K=false;var J=M.xhr();if(M.username){J.open(G,M.url,M.async,M.username,M.password)}else{J.open(G,M.url,M.async)}try{if(M.data){J.setRequestHeader("Content-Type",M.contentType)}if(M.ifModified){J.setRequestHeader("If-Modified-Since",o.lastModified[M.url]||"Thu, 01 Jan 1970 00:00:00 GMT")}J.setRequestHeader("X-Requested-With","XMLHttpRequest");J.setRequestHeader("Accept",M.dataType&&M.accepts[M.dataType]?M.accepts[M.dataType]+", */*":M.accepts._default)}catch(S){}if(M.beforeSend&&M.beforeSend(J,M)===false){if(M.global&&!--o.active){o.event.trigger("ajaxStop")}J.abort();return false}if(M.global){o.event.trigger("ajaxSend",[J,M])}var N=function(X){if(J.readyState==0){if(P){clearInterval(P);P=null;if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}}else{if(!K&&J&&(J.readyState==4||X=="timeout")){K=true;if(P){clearInterval(P);P=null}R=X=="timeout"?"timeout":!o.httpSuccess(J)?"error":M.ifModified&&o.httpNotModified(J,M.url)?"notmodified":"success";if(R=="success"){try{V=o.httpData(J,M.dataType,M)}catch(Z){R="parsererror"}}if(R=="success"){var Y;try{Y=J.getResponseHeader("Last-Modified")}catch(Z){}if(M.ifModified&&Y){o.lastModified[M.url]=Y}if(!W){I()}}else{o.handleError(M,J,R)}L();if(X){J.abort()}if(M.async){J=null}}}};if(M.async){var P=setInterval(N,13);if(M.timeout>0){setTimeout(function(){if(J&&!K){N("timeout")}},M.timeout)}}try{J.send(M.data)}catch(S){o.handleError(M,J,null,S)}if(!M.async){N()}function I(){if(M.success){M.success(V,R)}if(M.global){o.event.trigger("ajaxSuccess",[J,M])}}function L(){if(M.complete){M.complete(J,R)}if(M.global){o.event.trigger("ajaxComplete",[J,M])}if(M.global&&!--o.active){o.event.trigger("ajaxStop")}}return J},handleError:function(F,H,E,G){if(F.error){F.error(H,E,G)}if(F.global){o.event.trigger("ajaxError",[H,F,G])}},active:0,httpSuccess:function(F){try{return !F.status&&location.protocol=="file:"||(F.status>=200&&F.status<300)||F.status==304||F.status==1223}catch(E){}return false},httpNotModified:function(G,E){try{var H=G.getResponseHeader("Last-Modified");return G.status==304||H==o.lastModified[E]}catch(F){}return false},httpData:function(J,H,G){var F=J.getResponseHeader("content-type"),E=H=="xml"||!H&&F&&F.indexOf("xml")>=0,I=E?J.responseXML:J.responseText;if(E&&I.documentElement.tagName=="parsererror"){throw"parsererror"}if(G&&G.dataFilter){I=G.dataFilter(I,H)}if(typeof I==="string"){if(H=="script"){o.globalEval(I)}if(H=="json"){I=l["eval"]("("+I+")")}}return I},param:function(E){var G=[];function H(I,J){G[G.length]=encodeURIComponent(I)+"="+encodeURIComponent(J)}if(o.isArray(E)||E.jquery){o.each(E,function(){H(this.name,this.value)})}else{for(var F in E){if(o.isArray(E[F])){o.each(E[F],function(){H(F,this)})}else{H(F,o.isFunction(E[F])?E[F]():E[F])}}}return G.join("&").replace(/%20/g,"+")}});var m={},n,d=[["height","marginTop","marginBottom","paddingTop","paddingBottom"],["width","marginLeft","marginRight","paddingLeft","paddingRight"],["opacity"]];function t(F,E){var G={};o.each(d.concat.apply([],d.slice(0,E)),function(){G[this]=F});return G}o.fn.extend({show:function(J,L){if(J){return this.animate(t("show",3),J,L)}else{for(var H=0,F=this.length;H").appendTo("body");K=I.css("display");if(K==="none"){K="block"}I.remove();m[G]=K}o.data(this[H],"olddisplay",K)}}for(var H=0,F=this.length;H=0;H--){if(G[H].elem==this){if(E){G[H](true)}G.splice(H,1)}}});if(!E){this.dequeue()}return this}});o.each({slideDown:t("show",1),slideUp:t("hide",1),slideToggle:t("toggle",1),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"}},function(E,F){o.fn[E]=function(G,H){return this.animate(F,G,H)}});o.extend({speed:function(G,H,F){var E=typeof G==="object"?G:{complete:F||!F&&H||o.isFunction(G)&&G,duration:G,easing:F&&H||H&&!o.isFunction(H)&&H};E.duration=o.fx.off?0:typeof E.duration==="number"?E.duration:o.fx.speeds[E.duration]||o.fx.speeds._default;E.old=E.complete;E.complete=function(){if(E.queue!==false){o(this).dequeue()}if(o.isFunction(E.old)){E.old.call(this)}};return E},easing:{linear:function(G,H,E,F){return E+F*G},swing:function(G,H,E,F){return((-Math.cos(G*Math.PI)/2)+0.5)*F+E}},timers:[],fx:function(F,E,G){this.options=E;this.elem=F;this.prop=G;if(!E.orig){E.orig={}}}});o.fx.prototype={update:function(){if(this.options.step){this.options.step.call(this.elem,this.now,this)}(o.fx.step[this.prop]||o.fx.step._default)(this);if((this.prop=="height"||this.prop=="width")&&this.elem.style){this.elem.style.display="block"}},cur:function(F){if(this.elem[this.prop]!=null&&(!this.elem.style||this.elem.style[this.prop]==null)){return this.elem[this.prop]}var E=parseFloat(o.css(this.elem,this.prop,F));return E&&E>-10000?E:parseFloat(o.curCSS(this.elem,this.prop))||0},custom:function(I,H,G){this.startTime=e();this.start=I;this.end=H;this.unit=G||this.unit||"px";this.now=this.start;this.pos=this.state=0;var E=this;function F(J){return E.step(J)}F.elem=this.elem;if(F()&&o.timers.push(F)&&!n){n=setInterval(function(){var K=o.timers;for(var J=0;J=this.options.duration+this.startTime){this.now=this.end;this.pos=this.state=1;this.update();this.options.curAnim[this.prop]=true;var E=true;for(var F in this.options.curAnim){if(this.options.curAnim[F]!==true){E=false}}if(E){if(this.options.display!=null){this.elem.style.overflow=this.options.overflow;this.elem.style.display=this.options.display;if(o.css(this.elem,"display")=="none"){this.elem.style.display="block"}}if(this.options.hide){o(this.elem).hide()}if(this.options.hide||this.options.show){for(var I in this.options.curAnim){o.attr(this.elem.style,I,this.options.orig[I])}}this.options.complete.call(this.elem)}return false}else{var J=G-this.startTime;this.state=J/this.options.duration;this.pos=o.easing[this.options.easing||(o.easing.swing?"swing":"linear")](this.state,J,0,1,this.options.duration);this.now=this.start+((this.end-this.start)*this.pos);this.update()}return true}};o.extend(o.fx,{speeds:{slow:600,fast:200,_default:400},step:{opacity:function(E){o.attr(E.elem.style,"opacity",E.now)},_default:function(E){if(E.elem.style&&E.elem.style[E.prop]!=null){E.elem.style[E.prop]=E.now+E.unit}else{E.elem[E.prop]=E.now}}}});if(document.documentElement.getBoundingClientRect){o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}var G=this[0].getBoundingClientRect(),J=this[0].ownerDocument,F=J.body,E=J.documentElement,L=E.clientTop||F.clientTop||0,K=E.clientLeft||F.clientLeft||0,I=G.top+(self.pageYOffset||o.boxModel&&E.scrollTop||F.scrollTop)-L,H=G.left+(self.pageXOffset||o.boxModel&&E.scrollLeft||F.scrollLeft)-K;return{top:I,left:H}}}else{o.fn.offset=function(){if(!this[0]){return{top:0,left:0}}if(this[0]===this[0].ownerDocument.body){return o.offset.bodyOffset(this[0])}o.offset.initialized||o.offset.initialize();var J=this[0],G=J.offsetParent,F=J,O=J.ownerDocument,M,H=O.documentElement,K=O.body,L=O.defaultView,E=L.getComputedStyle(J,null),N=J.offsetTop,I=J.offsetLeft;while((J=J.parentNode)&&J!==K&&J!==H){M=L.getComputedStyle(J,null);N-=J.scrollTop,I-=J.scrollLeft;if(J===G){N+=J.offsetTop,I+=J.offsetLeft;if(o.offset.doesNotAddBorder&&!(o.offset.doesAddBorderForTableAndCells&&/^t(able|d|h)$/i.test(J.tagName))){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}F=G,G=J.offsetParent}if(o.offset.subtractsBorderForOverflowNotVisible&&M.overflow!=="visible"){N+=parseInt(M.borderTopWidth,10)||0,I+=parseInt(M.borderLeftWidth,10)||0}E=M}if(E.position==="relative"||E.position==="static"){N+=K.offsetTop,I+=K.offsetLeft}if(E.position==="fixed"){N+=Math.max(H.scrollTop,K.scrollTop),I+=Math.max(H.scrollLeft,K.scrollLeft)}return{top:N,left:I}}}o.offset={initialize:function(){if(this.initialized){return}var L=document.body,F=document.createElement("div"),H,G,N,I,M,E,J=L.style.marginTop,K='
    ';M={position:"absolute",top:0,left:0,margin:0,border:0,width:"1px",height:"1px",visibility:"hidden"};for(E in M){F.style[E]=M[E]}F.innerHTML=K;L.insertBefore(F,L.firstChild);H=F.firstChild,G=H.firstChild,I=H.nextSibling.firstChild.firstChild;this.doesNotAddBorder=(G.offsetTop!==5);this.doesAddBorderForTableAndCells=(I.offsetTop===5);H.style.overflow="hidden",H.style.position="relative";this.subtractsBorderForOverflowNotVisible=(G.offsetTop===-5);L.style.marginTop="1px";this.doesNotIncludeMarginInBodyOffset=(L.offsetTop===0);L.style.marginTop=J;L.removeChild(F);this.initialized=true},bodyOffset:function(E){o.offset.initialized||o.offset.initialize();var G=E.offsetTop,F=E.offsetLeft;if(o.offset.doesNotIncludeMarginInBodyOffset){G+=parseInt(o.curCSS(E,"marginTop",true),10)||0,F+=parseInt(o.curCSS(E,"marginLeft",true),10)||0}return{top:G,left:F}}};o.fn.extend({position:function(){var I=0,H=0,F;if(this[0]){var G=this.offsetParent(),J=this.offset(),E=/^body|html$/i.test(G[0].tagName)?{top:0,left:0}:G.offset();J.top-=j(this,"marginTop");J.left-=j(this,"marginLeft");E.top+=j(G,"borderTopWidth");E.left+=j(G,"borderLeftWidth");F={top:J.top-E.top,left:J.left-E.left}}return F},offsetParent:function(){var E=this[0].offsetParent||document.body;while(E&&(!/^body|html$/i.test(E.tagName)&&o.css(E,"position")=="static")){E=E.offsetParent}return o(E)}});o.each(["Left","Top"],function(F,E){var G="scroll"+E;o.fn[G]=function(H){if(!this[0]){return null}return H!==g?this.each(function(){this==l||this==document?l.scrollTo(!F?H:o(l).scrollLeft(),F?H:o(l).scrollTop()):this[G]=H}):this[0]==l||this[0]==document?self[F?"pageYOffset":"pageXOffset"]||o.boxModel&&document.documentElement[G]||document.body[G]:this[0][G]}});o.each(["Height","Width"],function(I,G){var E=I?"Left":"Top",H=I?"Right":"Bottom",F=G.toLowerCase();o.fn["inner"+G]=function(){return this[0]?o.css(this[0],F,false,"padding"):null};o.fn["outer"+G]=function(K){return this[0]?o.css(this[0],F,false,K?"margin":"border"):null};var J=G.toLowerCase();o.fn[J]=function(K){return this[0]==l?document.compatMode=="CSS1Compat"&&document.documentElement["client"+G]||document.body["client"+G]:this[0]==document?Math.max(document.documentElement["client"+G],document.body["scroll"+G],document.documentElement["scroll"+G],document.body["offset"+G],document.documentElement["offset"+G]):K===g?(this.length?o.css(this[0],J):null):this.css(J,typeof K==="string"?K:K+"px")}})})(); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.suggest.js b/spec/test_app/public/javascripts/jquery.suggest.js new file mode 100644 index 0000000..df8784f --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.suggest.js @@ -0,0 +1,276 @@ + + /* + * jquery.suggest 1.1 - 2007-08-06 + * + * Uses code and techniques from following libraries: + * 1. http://www.dyve.net/jquery/?autocomplete + * 2. http://dev.jquery.com/browser/trunk/plugins/interface/iautocompleter.js + * + * All the new stuff written by Peter Vulgaris (www.vulgarisoip.com) + * Feel free to do whatever you want with this file + * + */ + + (function($) { + var defaults = { + delay: 100, + resultsClass: 'jquery-suggestion-results', + selectClass: 'jquery-suggestion-select', + matchClass: 'jquery-suggestion-match', + minchars: 2, + onSelect: function($input, $result) { + $input.val($result.data('autocomplete:value')); + }, + maxCacheSize: 65536, + source: '', + method: 'get', + dataType: 'json', + params: '', + queryParam: 'q' + }; + + $.suggest = function(input, options) { + options = $.extend({}, defaults, options); + + var $input = $(input).attr("autocomplete", "off"); + var $results = $('
      '); + + var timeout = false; // hold timeout ID for suggestion results to appear + var prevLength = 0; // last recorded length of $input.val() + var cache = []; // cache MRU list + var cacheSize = 0; // size of cache in chars (bytes?) + + $results.addClass(options.resultsClass).appendTo('body').hide(); + + resetPosition(); + $(window) + .load(resetPosition) // just in case user is changing size of page while loading + .resize(resetPosition); + + $input.blur(function() { + setTimeout(function() { $results.hide() }, 200); + }); + + // help IE users if possible + if ($results.bgiframe) $results.bgiframe(); + + // I really hate browser detection, but I don't see any other way + if ($.browser.mozilla) + $input.keypress(processKey); // onkeypress repeats arrow keys in Mozilla/Opera + else + $input.keydown(processKey); // onkeydown repeats arrow keys in IE/Safari + + function resetPosition() { + // requires jquery.dimension plugin + var offset = $input.offset(); + $results.css({ + top: (offset.top + input.offsetHeight) + 'px', + left: offset.left + 'px' + }); + } + + function processKey(e) { + // handling up/down/escape requires results to be visible + // handling enter/tab requires that AND a result to be selected + if ((/27$|38$|40$/.test(e.keyCode) && $results.is(':visible')) || + (/^13$|^9$/.test(e.keyCode) && getCurrentResult())) { + + if (e.preventDefault) + e.preventDefault(); + if (e.stopPropagation) + e.stopPropagation(); + + e.cancelBubble = true; + e.returnValue = false; + + switch(e.keyCode) { + case 38: // up + prevResult(); + break; + case 40: // down + nextResult(); + break; + case 9: // tab + case 13: // return + selectCurrentResult(); + break; + case 27: // escape + $results.hide(); + break; + } + } + else if ($input.val().length != prevLength) { + if (timeout) + clearTimeout(timeout); + timeout = setTimeout(suggest, options.delay); + prevLength = $input.val().length; + } + } + + function suggest() { + var q = $.trim($input.val()); + + if (q.length >= options.minchars) { + cached = checkCache(q); + if (cached) { + displayItems(cached['items']); + } + else { + var params = options.queryParam + '=' + q + (options.params.length ? '&' + options.params : ''); + $.ajax({ + type: options.method, + url: options.source, + dataType: options.dataType, + data: params, + success: function(data) { + $results.hide(); + + displayItems(data); + addToCache(q, data); + }, + error: function(xmlhttp, text) { + $results.hide(); + alert(text); + } + }); + } + } + else { + $results.hide(); + } + } + + function checkCache(q) { + for (var i = 0; i < cache.length; i++) + if (cache[i]['q'] == q) { + cache.unshift(cache.splice(i, 1)[0]); + return cache[0]; + } + return false; + } + + function addToCache(q, items) { + var size = 0; + $.each(items, function() { + ++size; + }); + + while (cache.length && (cacheSize + size > options.maxCacheSize)) { + var cached = cache.pop(); + cacheSize -= cached['size']; + } + + cache.push({ + q: q, + size: size, + items: items + }); + cacheSize += size; + } + + function displayItems(items) { + if (!items) + return; + var empty = true; + $results.empty(); + $.each(items, function(value, display) { + var $item = $('
    • ').html(display).data('autocomplete:value', value); + $results.append($item); + empty = false; + }); + + if (empty) { + $results.hide(); + return; + } + + resetPosition(); + $results + .width($input.width()) + .show() + .children('li') + .mouseover(function() { + $results.children('li').removeClass(options.selectClass); + $(this).addClass(options.selectClass); + }) + .click(function(e) { + e.preventDefault(); + e.stopPropagation(); + selectCurrentResult(); + }); + } + + function parseTxt(txt, q) { + var items = []; + var tokens = txt.split(options.delimiter); + + // parse returned data for non-empty items + for (var i = 0; i < tokens.length; i++) { + var token = $.trim(tokens[i]); + if (token) { + token = token.replace( + new RegExp(q, 'ig'), + function(q) { return '' + q + '' } + ); + items[items.length] = token; + } + } + return items; + } + + function getCurrentResult() { + if (!$results.is(':visible')) + return false; + + var $currentResult = $results.children('li.' + options.selectClass); + if (!$currentResult.length) + $currentResult = false; + + return $currentResult; + } + + function selectCurrentResult() { + $currentResult = getCurrentResult(); + + if ($currentResult) { + options.onSelect.call(this, $input, $currentResult); + $results.hide(); + } + } + + function nextResult() { + $currentResult = getCurrentResult(); + + if ($currentResult) + $currentResult + .removeClass(options.selectClass) + .next() + .addClass(options.selectClass); + else + $results.children('li:first-child').addClass(options.selectClass); + } + + function prevResult() { + $currentResult = getCurrentResult(); + + if ($currentResult) + $currentResult + .removeClass(options.selectClass) + .prev() + .addClass(options.selectClass); + else + $results.children('li:last-child').addClass(options.selectClass); + } + } + + $.fn.suggest = function(source, options) { + if (!source) + return; + options.source = source; + this.each(function() { + new $.suggest(this, options); + }); + return this; + }; + })(jQuery); + diff --git a/spec/test_app/public/javascripts/jquery.template.js b/spec/test_app/public/javascripts/jquery.template.js new file mode 100644 index 0000000..5ad757d --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.template.js @@ -0,0 +1,255 @@ +/** + * jQuery Templates + * + * Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) + * and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses. + * + * Written by: Stan Lemon + * + * Based off of the Ext.Template library, available at: + * http://www.extjs.com + * + * This library provides basic templating functionality, allowing for macro-based + * templates within jQuery. + * + * Basic Usage: + * + * var t = $.template('
      Hello ${name}, how are you ${question}? I am ${me:substr(0,10)}
      '); + * + * $(selector).append( t , { + * name: 'Stan', + * question: 'feeling', + * me: 'doing quite well myself, thank you very much!' + * }); + * + * Requires: jQuery 1.2+ + * + * + * @todo Add callbacks to the DOM manipulation methods, so that events can be bound + * to template nodes after creation. + */ +(function($){ + + /** + * Create a New Template + */ + $.template = function(html, options) { + return new $.template.instance(html, options); + }; + + /** + * Template constructor - Creates a new template instance. + * + * @param html The string of HTML to be used for the template. + * @param options An object of configurable options. Currently + * you can toggle compile as a boolean value and set a custom + * template regular expression on the property regx by + * specifying the key of the regx to use from the regx object. + */ + $.template.instance = function(html, options) { + // If a custom regular expression has been set, grab it from the regx object + if ( options && options['regx'] ) options.regx = this.regx[ options.regx ]; + + this.options = $.extend({ + compile: false, + regx: this.regx.standard + }, options || {}); + + this.html = html; + + if (this.options.compile) { + this.compile(); + } + this.isTemplate = true; + }; + + /** + * Regular Expression for Finding Variables + * + * The default pattern looks for variables in JSP style, the form of: ${variable} + * There are also regular expressions available for ext-style variables and + * jTemplate style variables. + * + * You can add your own regular expressions for variable ussage by doing. + * $.extend({ $.template.re , { + * myvartype: /...../g + * } + * + * Then when creating a template do: + * var t = $.template("
      ...
      ", { regx: 'myvartype' }); + */ + $.template.regx = $.template.instance.prototype.regx = { + jsp: /\$\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, + ext: /\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}/g, + jtemplates: /\{\{([\w-]+)(?:\:([\w\.]*)(?:\((.*?)?\))?)?\}\}/g + }; + + /** + * Set the standard regular expression to be used. + */ + $.template.regx.standard = $.template.regx.jsp; + + /** + * Variable Helper Methods + * + * This is a collection of methods which can be used within the variable syntax, ie: + * ${variable:substr(0,30)} Which would only print a substring, 30 characters in length + * begining at the first character for the variable named "variable". + * + * A basic substring helper is provided as an example of how you can define helpers. + * To add more helpers simply do: + * $.extend( $.template.helpers , { + * sampleHelper: function() { ... } + * }); + */ + $.template.helpers = $.template.instance.prototype.helpers = { + substr : function(value, start, length){ + return String(value).substr(start, length); + } + }; + + + /** + * Template Instance Methods + */ + $.extend( $.template.instance.prototype, { + + /** + * Apply Values to a Template + * + * This is the macro-work horse of the library, it receives an object + * and the properties of that objects are assigned to the template, where + * the variables in the template represent keys within the object itself. + * + * @param values An object of properties mapped to template variables + */ + apply: function(values) { + if (this.options.compile) { + return this.compiled(values); + } else { + var tpl = this; + var fm = this.helpers; + + var fn = function(m, name, format, args) { + if (format) { + if (format.substr(0, 5) == "this."){ + return tpl.call(format.substr(5), values[name], values); + } else { + if (args) { + // quoted values are required for strings in compiled templates, + // but for non compiled we need to strip them + // quoted reversed for jsmin + var re = /^\s*['"](.*)["']\s*$/; + args = args.split(','); + + for(var i = 0, len = args.length; i < len; i++) { + args[i] = args[i].replace(re, "$1"); + } + args = [values[name]].concat(args); + } else { + args = [values[name]]; + } + + return fm[format].apply(fm, args); + } + } else { + return values[name] !== undefined ? values[name] : ""; + } + }; + + return this.html.replace(this.options.regx, fn); + } + }, + + /** + * Compile a template for speedier usage + */ + compile: function() { + var sep = $.browser.mozilla ? "+" : ","; + var fm = this.helpers; + + var fn = function(m, name, format, args){ + if (format) { + args = args ? ',' + args : ""; + + if (format.substr(0, 5) != "this.") { + format = "fm." + format + '('; + } else { + format = 'this.call("'+ format.substr(5) + '", '; + args = ", values"; + } + } else { + args= ''; format = "(values['" + name + "'] == undefined ? '' : "; + } + return "'"+ sep + format + "values['" + name + "']" + args + ")"+sep+"'"; + }; + + var body; + + if ($.browser.mozilla) { + body = "this.compiled = function(values){ return '" + + this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.options.regx, fn) + + "';};"; + } else { + body = ["this.compiled = function(values){ return ['"]; + body.push(this.html.replace(/\\/g, '\\\\').replace(/(\r\n|\n)/g, '\\n').replace(/'/g, "\\'").replace(this.options.regx, fn)); + body.push("'].join('');};"); + body = body.join(''); + } + eval(body); + return this; + } + }); + + + /** + * Save a reference in this local scope to the original methods which we're + * going to overload. + **/ + var $_old = { + domManip: $.fn.domManip, + text: $.fn.text, + html: $.fn.html + }; + + /** + * Overwrite the domManip method so that we can use things like append() by passing a + * template object and macro parameters. + */ + $.fn.domManip = function( args, table, reverse, callback ) { + if (args[0].isTemplate) { + // Apply the template and it's arguments... + args[0] = args[0].apply( args[1] ); + // Get rid of the arguements, we don't want to pass them on + delete args[1]; + } + + // Call the original method + var r = $_old.domManip.apply(this, arguments); + + return r; + }; + + /** + * Overwrite the html() method + */ + $.fn.html = function( value , o ) { + if (value && value.isTemplate) var value = value.apply( o ); + + var r = $_old.html.apply(this, [value]); + + return r; + }; + + /** + * Overwrite the text() method + */ + $.fn.text = function( value , o ) { + if (value && value.isTemplate) var value = value.apply( o ); + + var r = $_old.text.apply(this, [value]); + + return r; + }; + +})(jQuery); diff --git a/spec/test_app/public/javascripts/jquery.tokeninput.js b/spec/test_app/public/javascripts/jquery.tokeninput.js new file mode 100644 index 0000000..942c259 --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.tokeninput.js @@ -0,0 +1,618 @@ +/* + * jQuery Plugin: Tokenizing Autocomplete Text Entry + * Version 1.1 + * + * Copyright (c) 2009 James Smith (http://loopj.com) + * Licensed jointly under the GPL and MIT licenses, + * choose which one suits your project best! + * + */ + +(function($) { + +$.fn.tokenInput = function (url, options) { + var settings = $.extend({ + url: url, + hintText: "Type in a search term", + noResultsText: "No results", + searchingText: "Searching...", + searchDelay: 300, + prePopulateFromInput: false, + minChars: 1, + tokenLimit: null, + jsonContainer: null, + method: "GET", + contentType: "json", + queryParam: "q", + onResult: null + }, options); + + settings.classes = $.extend({ + tokenList: "token-input-list", + token: "token-input-token", + tokenDelete: "token-input-delete-token", + selectedToken: "token-input-selected-token", + highlightedToken: "token-input-highlighted-token", + dropdown: "token-input-dropdown", + dropdownItem: "token-input-dropdown-item", + dropdownItem2: "token-input-dropdown-item2", + selectedDropdownItem: "token-input-selected-dropdown-item", + inputToken: "token-input-input-token" + }, options.classes); + + return this.each(function () { + var list = new $.TokenList(this, settings); + }); +}; + +$.TokenList = function (input, settings) { + // + // Variables + // + + // Input box position "enum" + var POSITION = { + BEFORE: 0, + AFTER: 1, + END: 2 + }; + + // Keys "enum" + var KEY = { + BACKSPACE: 8, + TAB: 9, + RETURN: 13, + ESC: 27, + LEFT: 37, + UP: 38, + RIGHT: 39, + DOWN: 40, + COMMA: 188 + }; + + // Save the tokens + var saved_tokens = []; + + // Keep track of the number of tokens in the list + var token_count = 0; + + // Basic cache to save on db hits + var cache = new $.TokenList.Cache(); + + // Keep track of the timeout + var timeout; + + // Create a new text input an attach keyup events + var input_box = $("") + .css({ + outline: "none" + }) + .focus(function () { + if (settings.tokenLimit == null || settings.tokenLimit != token_count) { + show_dropdown_hint(); + } + }) + .blur(function () { + hide_dropdown(); + }) + .keydown(function (event) { + var previous_token; + var next_token; + + switch(event.keyCode) { + case KEY.LEFT: + case KEY.RIGHT: + case KEY.UP: + case KEY.DOWN: + if(!$(this).val()) { + previous_token = input_token.prev(); + next_token = input_token.next(); + + if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) { + // Check if there is a previous/next token and it is selected + if(event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) { + deselect_token($(selected_token), POSITION.BEFORE); + } else { + deselect_token($(selected_token), POSITION.AFTER); + } + } else if((event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) && previous_token.length) { + // We are moving left, select the previous token if it exists + select_token($(previous_token.get(0))); + } else if((event.keyCode == KEY.RIGHT || event.keyCode == KEY.DOWN) && next_token.length) { + // We are moving right, select the next token if it exists + select_token($(next_token.get(0))); + } + } else { + var dropdown_item = null; + + if(event.keyCode == KEY.DOWN || event.keyCode == KEY.RIGHT) { + dropdown_item = $(selected_dropdown_item).next(); + } else { + dropdown_item = $(selected_dropdown_item).prev(); + } + + if(dropdown_item.length) { + select_dropdown_item(dropdown_item); + } + return false; + } + break; + + case KEY.BACKSPACE: + previous_token = input_token.prev(); + + if(!$(this).val().length) { + if(selected_token) { + delete_token($(selected_token)); + } else if(previous_token.length) { + select_token($(previous_token.get(0))); + } + + return false; + } else if($(this).val().length == 1) { + hide_dropdown(); + } else { + // set a timeout just long enough to let this function finish. + setTimeout(function(){do_search(false);}, 5); + } + break; + + case KEY.TAB: + case KEY.RETURN: + case KEY.COMMA: + if(selected_dropdown_item) { + add_token($(selected_dropdown_item)); + return false; + } + break; + + case KEY.ESC: + hide_dropdown(); + return true; + + default: + if(is_printable_character(event.keyCode)) { + // set a timeout just long enough to let this function finish. + setTimeout(function(){do_search(false);}, 5); + } + break; + } + }); + + // Keep a reference to the original input box + var hidden_input = $(input) + .hide() + .focus(function () { + input_box.focus(); + }) + .blur(function () { + input_box.blur(); + }); + + + if(settings.prePopulateFromInput){ + settings.prePopulate = []; + if(hidden_input.attr('data-names') != undefined){ + var names = $.parseJSON(hidden_input.attr('data-names')); + } + $.each(hidden_input.val().trim().split(','), function(i, val) { + if(val != '' && names != undefined && names[val] != undefined){ + settings.prePopulate.push({ id : val, name : names[val] }); + } + }); + hidden_input.val(hidden_input.val() + ','); + + } + + + // Keep a reference to the selected token and dropdown item + var selected_token = null; + var selected_dropdown_item = null; + + // The list to store the token items in + var token_list = $("
        ") + .addClass(settings.classes.tokenList) + .insertAfter(hidden_input) + .click(function (event) { + var li = get_element_from_event(event, "li"); + if(li && li.get(0) != input_token.get(0)) { + toggle_select_token(li); + return false; + } else { + input_box.focus(); + + if(selected_token) { + deselect_token($(selected_token), POSITION.END); + } + } + }) + .mouseover(function (event) { + var li = get_element_from_event(event, "li"); + if(li && selected_token !== this) { + li.addClass(settings.classes.highlightedToken); + } + }) + .mouseout(function (event) { + var li = get_element_from_event(event, "li"); + if(li && selected_token !== this) { + li.removeClass(settings.classes.highlightedToken); + } + }) + .mousedown(function (event) { + // Stop user selecting text on tokens + var li = get_element_from_event(event, "li"); + if(li){ + return false; + } + }); + + + // The list to store the dropdown items in + var dropdown = $("
        ") + .addClass(settings.classes.dropdown) + .insertAfter(token_list) + .hide(); + + // The token holding the input box + var input_token = $("
      • ") + .addClass(settings.classes.inputToken) + .appendTo(token_list) + .append(input_box); + + init_list(); + + // + // Functions + // + + + // Pre-populate list if items exist + function init_list () { + li_data = settings.prePopulate; + + if(li_data && li_data.length) { + for(var i in li_data) { + var this_token = $("
      • "+li_data[i].name+"

      • ") + .addClass(settings.classes.token) + .insertBefore(input_token); + + $("x") + .addClass(settings.classes.tokenDelete) + .appendTo(this_token) + .click(function () { + delete_token($(this).parent()); + return false; + }); + + $.data(this_token.get(0), "tokeninput", {"id": li_data[i].id, "name": li_data[i].name}); + + // Clear input box and make sure it keeps focus + input_box + .val("") + .focus(); + + // Don't show the help dropdown, they've got the idea + hide_dropdown(); + + // Save this token id + var id_string = li_data[i].id + "," + + // Leave input value alone if using prePopulateFromInput + if(!settings.prePopulateFromInput){ + hidden_input.val(hidden_input.val() + id_string); + } + } + } + + } + + + function is_printable_character(keycode) { + if((keycode >= 48 && keycode <= 90) || // 0-1a-z + (keycode >= 96 && keycode <= 111) || // numpad 0-9 + - / * . + (keycode >= 186 && keycode <= 192) || // ; = , - . / ^ + (keycode >= 219 && keycode <= 222) // ( \ ) ' + ) { + return true; + } else { + return false; + } + } + + // Get an element of a particular type from an event (click/mouseover etc) + function get_element_from_event (event, element_type) { + var target = $(event.target); + var element = null; + + if(target.is(element_type)) { + element = target; + } else if(target.parent(element_type).length) { + element = target.parent(element_type+":first"); + } + + return element; + } + + // Inner function to a token to the list + function insert_token(id, value) { + var this_token = $("
      • "+ value +"

      • ") + .addClass(settings.classes.token) + .insertBefore(input_token); + + // The 'delete token' button + $("x") + .addClass(settings.classes.tokenDelete) + .appendTo(this_token) + .click(function () { + delete_token($(this).parent()); + return false; + }); + + $.data(this_token.get(0), "tokeninput", {"id": id, "name": value}); + + return this_token; + } + + // Add a token to the token list based on user input + function add_token (item) { + var li_data = $.data(item.get(0), "tokeninput"); + var this_token = insert_token(li_data.id, li_data.name); + + // Clear input box and make sure it keeps focus + input_box + .val("") + .focus(); + + // Don't show the help dropdown, they've got the idea + hide_dropdown(); + + // Save this token id + var id_string = li_data.id + "," + hidden_input.val(hidden_input.val() + id_string); + + token_count++; + + if(settings.tokenLimit != null && settings.tokenLimit >= token_count) { + input_box.hide(); + hide_dropdown(); + } + } + + // Select a token in the token list + function select_token (token) { + token.addClass(settings.classes.selectedToken); + selected_token = token.get(0); + + // Hide input box + input_box.val(""); + + // Hide dropdown if it is visible (eg if we clicked to select token) + hide_dropdown(); + } + + // Deselect a token in the token list + function deselect_token (token, position) { + token.removeClass(settings.classes.selectedToken); + selected_token = null; + + if(position == POSITION.BEFORE) { + input_token.insertBefore(token); + } else if(position == POSITION.AFTER) { + input_token.insertAfter(token); + } else { + input_token.appendTo(token_list); + } + + // Show the input box and give it focus again + input_box.focus(); + } + + // Toggle selection of a token in the token list + function toggle_select_token (token) { + if(selected_token == token.get(0)) { + deselect_token(token, POSITION.END); + } else { + if(selected_token) { + deselect_token($(selected_token), POSITION.END); + } + select_token(token); + } + } + + // Delete a token from the token list + function delete_token (token) { + // Remove the id from the saved list + var token_data = $.data(token.get(0), "tokeninput"); + + // Delete the token + token.remove(); + selected_token = null; + + // Show the input box and give it focus again + input_box.focus(); + + // Delete this token's id from hidden input + var str = hidden_input.val() + var start = str.indexOf(token_data.id+","); + var end = str.indexOf(",", start) + 1; + + if(end >= str.length) { + hidden_input.val(str.slice(0, start)); + } else { + hidden_input.val(str.slice(0, start) + str.slice(end, str.length)); + } + + token_count--; + + if (settings.tokenLimit != null) { + input_box + .show() + .val("") + .focus(); + } + } + + // Hide and clear the results dropdown + function hide_dropdown () { + dropdown.hide().empty(); + selected_dropdown_item = null; + } + + function show_dropdown_searching () { + dropdown + .html("

        "+settings.searchingText+"

        ") + .show(); + } + + function show_dropdown_hint () { + dropdown + .html("

        "+settings.hintText+"

        ") + .show(); + } + + // Highlight the query part of the search term + function highlight_term(value, term) { + return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "$1"); + } + + // Populate the results dropdown with some results + function populate_dropdown (query, results) { + if(results.length) { + dropdown.empty(); + var dropdown_ul = $("
          ") + .appendTo(dropdown) + .mouseover(function (event) { + select_dropdown_item(get_element_from_event(event, "li")); + }) + .mousedown(function (event) { + add_token(get_element_from_event(event, "li")); + return false; + }) + .hide(); + + for(var i in results) { + if (results.hasOwnProperty(i)) { + var this_li = $("
        • "+highlight_term(results[i].name, query)+"
        • ") + .appendTo(dropdown_ul); + + if(i%2) { + this_li.addClass(settings.classes.dropdownItem); + } else { + this_li.addClass(settings.classes.dropdownItem2); + } + + if(i == 0) { + select_dropdown_item(this_li); + } + + $.data(this_li.get(0), "tokeninput", {"id": results[i].id, "name": results[i].name}); + } + } + + dropdown.show(); + dropdown_ul.slideDown("fast"); + + } else { + dropdown + .html("

          "+settings.noResultsText+"

          ") + .show(); + } + } + + // Highlight an item in the results dropdown + function select_dropdown_item (item) { + if(item) { + if(selected_dropdown_item) { + deselect_dropdown_item($(selected_dropdown_item)); + } + + item.addClass(settings.classes.selectedDropdownItem); + selected_dropdown_item = item.get(0); + } + } + + // Remove highlighting from an item in the results dropdown + function deselect_dropdown_item (item) { + item.removeClass(settings.classes.selectedDropdownItem); + selected_dropdown_item = null; + } + + // Do a search and show the "searching" dropdown if the input is longer + // than settings.minChars + function do_search(immediate) { + var query = input_box.val().toLowerCase(); + + if (query && query.length) { + if(selected_token) { + deselect_token($(selected_token), POSITION.AFTER); + } + if (query.length >= settings.minChars) { + show_dropdown_searching(); + if (immediate) { + run_search(query); + } else { + clearTimeout(timeout); + timeout = setTimeout(function(){run_search(query);}, settings.searchDelay); + } + } else { + hide_dropdown(); + } + } + } + + // Do the actual search + function run_search(query) { + var cached_results = cache.get(query); + if(cached_results) { + populate_dropdown(query, cached_results); + } else { + var queryStringDelimiter = settings.url.indexOf("?") < 0 ? "?" : "&"; + var callback = function(results) { + if($.isFunction(settings.onResult)) { + results = settings.onResult.call(this, results); + } + cache.add(query, settings.jsonContainer ? results[settings.jsonContainer] : results); + populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results); + }; + + if(settings.method == "POST") { + $.post(settings.url + queryStringDelimiter + settings.queryParam + "=" + query, {}, callback, settings.contentType); + } else { + $.get(settings.url + queryStringDelimiter + settings.queryParam + "=" + query, {}, callback, settings.contentType); + } + } + } +}; + +// Really basic cache for the results +$.TokenList.Cache = function (options) { + var settings = $.extend({ + max_size: 50 + }, options); + + var data = {}; + var size = 0; + + var flush = function () { + data = {}; + size = 0; + }; + + this.add = function (query, results) { + if(size > settings.max_size) { + flush(); + } + + if(!data[query]) { + size++; + } + + data[query] = results; + }; + + this.get = function (query) { + return data[query]; + }; +}; + +})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jquery.validate.min.js b/spec/test_app/public/javascripts/jquery.validate.min.js new file mode 100644 index 0000000..a1a5fbb --- /dev/null +++ b/spec/test_app/public/javascripts/jquery.validate.min.js @@ -0,0 +1,16 @@ +/* + * jQuery validation plug-in 1.5.5 + * + * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ + * http://docs.jquery.com/Plugins/Validation + * + * Copyright (c) 2006 - 2008 Jörn Zaefferer + * + * $Id: jquery.validate.js 6403 2009-06-17 14:27:16Z joern.zaefferer $ + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +(function($){$.extend($.fn,{validate:function(options){if(!this.length){options&&options.debug&&window.console&&console.warn("nothing selected, can't validate, returning nothing");return;}var validator=$.data(this[0],'validator');if(validator){return validator;}validator=new $.validator(options,this[0]);$.data(this[0],'validator',validator);if(validator.settings.onsubmit){this.find("input, button").filter(".cancel").click(function(){validator.cancelSubmit=true;});if(validator.settings.submitHandler){this.find("input, button").filter(":submit").click(function(){validator.submitButton=this;});}this.submit(function(event){if(validator.settings.debug)event.preventDefault();function handle(){if(validator.settings.submitHandler){if(validator.submitButton){var hidden=$("").attr("name",validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm);}validator.settings.submitHandler.call(validator,validator.currentForm);if(validator.submitButton){hidden.remove();}return false;}return true;}if(validator.cancelSubmit){validator.cancelSubmit=false;return handle();}if(validator.form()){if(validator.pendingRequest){validator.formSubmitted=true;return false;}return handle();}else{validator.focusInvalid();return false;}});}return validator;},valid:function(){if($(this[0]).is('form')){return this.validate().form();}else{var valid=true;var validator=$(this[0].form).validate();this.each(function(){valid&=validator.element(this);});return valid;}},removeAttrs:function(attributes){var result={},$element=this;$.each(attributes.split(/\s/),function(index,value){result[value]=$element.attr(value);$element.removeAttr(value);});return result;},rules:function(command,argument){var element=this[0];if(command){var settings=$.data(element.form,'validator').settings;var staticRules=settings.rules;var existingRules=$.validator.staticRules(element);switch(command){case"add":$.extend(existingRules,$.validator.normalizeRule(argument));staticRules[element.name]=existingRules;if(argument.messages)settings.messages[element.name]=$.extend(settings.messages[element.name],argument.messages);break;case"remove":if(!argument){delete staticRules[element.name];return existingRules;}var filtered={};$.each(argument.split(/\s/),function(index,method){filtered[method]=existingRules[method];delete existingRules[method];});return filtered;}}var data=$.validator.normalizeRules($.extend({},$.validator.metadataRules(element),$.validator.classRules(element),$.validator.attributeRules(element),$.validator.staticRules(element)),element);if(data.required){var param=data.required;delete data.required;data=$.extend({required:param},data);}return data;}});$.extend($.expr[":"],{blank:function(a){return!$.trim(a.value);},filled:function(a){return!!$.trim(a.value);},unchecked:function(a){return!a.checked;}});$.validator=function(options,form){this.settings=$.extend({},$.validator.defaults,options);this.currentForm=form;this.init();};$.validator.format=function(source,params){if(arguments.length==1)return function(){var args=$.makeArray(arguments);args.unshift(source);return $.validator.format.apply(this,args);};if(arguments.length>2&¶ms.constructor!=Array){params=$.makeArray(arguments).slice(1);}if(params.constructor!=Array){params=[params];}$.each(params,function(i,n){source=source.replace(new RegExp("\\{"+i+"\\}","g"),n);});return source;};$.extend($.validator,{defaults:{messages:{},groups:{},rules:{},errorClass:"error",validClass:"valid",errorElement:"label",focusInvalid:true,errorContainer:$([]),errorLabelContainer:$([]),onsubmit:true,ignore:[],ignoreTitle:false,onfocusin:function(element){this.lastActive=element;if(this.settings.focusCleanup&&!this.blockFocusCleanup){this.settings.unhighlight&&this.settings.unhighlight.call(this,element,this.settings.errorClass,this.settings.validClass);this.errorsFor(element).hide();}},onfocusout:function(element){if(!this.checkable(element)&&(element.name in this.submitted||!this.optional(element))){this.element(element);}},onkeyup:function(element){if(element.name in this.submitted||element==this.lastElement){this.element(element);}},onclick:function(element){if(element.name in this.submitted)this.element(element);},highlight:function(element,errorClass,validClass){$(element).addClass(errorClass).removeClass(validClass);},unhighlight:function(element,errorClass,validClass){$(element).removeClass(errorClass).addClass(validClass);}},setDefaults:function(settings){$.extend($.validator.defaults,settings);},messages:{required:"This field is required.",remote:"Please fix this field.",email:"Please enter a valid email address.",url:"Please enter a valid URL.",date:"Please enter a valid date.",dateISO:"Please enter a valid date (ISO).",dateDE:"Bitte geben Sie ein gültiges Datum ein.",number:"Please enter a valid number.",numberDE:"Bitte geben Sie eine Nummer ein.",digits:"Please enter only digits",creditcard:"Please enter a valid credit card number.",equalTo:"Please enter the same value again.",accept:"Please enter a value with a valid extension.",maxlength:$.validator.format("Please enter no more than {0} characters."),minlength:$.validator.format("Please enter at least {0} characters."),rangelength:$.validator.format("Please enter a value between {0} and {1} characters long."),range:$.validator.format("Please enter a value between {0} and {1}."),max:$.validator.format("Please enter a value less than or equal to {0}."),min:$.validator.format("Please enter a value greater than or equal to {0}.")},autoCreateRanges:false,prototype:{init:function(){this.labelContainer=$(this.settings.errorLabelContainer);this.errorContext=this.labelContainer.length&&this.labelContainer||$(this.currentForm);this.containers=$(this.settings.errorContainer).add(this.settings.errorLabelContainer);this.submitted={};this.valueCache={};this.pendingRequest=0;this.pending={};this.invalid={};this.reset();var groups=(this.groups={});$.each(this.settings.groups,function(key,value){$.each(value.split(/\s/),function(index,name){groups[name]=key;});});var rules=this.settings.rules;$.each(rules,function(key,value){rules[key]=$.validator.normalizeRule(value);});function delegate(event){var validator=$.data(this[0].form,"validator");validator.settings["on"+event.type]&&validator.settings["on"+event.type].call(validator,this[0]);}$(this.currentForm).delegate("focusin focusout keyup",":text, :password, :file, select, textarea",delegate).delegate("click",":radio, :checkbox",delegate);if(this.settings.invalidHandler)$(this.currentForm).bind("invalid-form.validate",this.settings.invalidHandler);},form:function(){this.checkForm();$.extend(this.submitted,this.errorMap);this.invalid=$.extend({},this.errorMap);if(!this.valid())$(this.currentForm).triggerHandler("invalid-form",[this]);this.showErrors();return this.valid();},checkForm:function(){this.prepareForm();for(var i=0,elements=(this.currentElements=this.elements());elements[i];i++){this.check(elements[i]);}return this.valid();},element:function(element){element=this.clean(element);this.lastElement=element;this.prepareElement(element);this.currentElements=$(element);var result=this.check(element);if(result){delete this.invalid[element.name];}else{this.invalid[element.name]=true;}if(!this.numberOfInvalids()){this.toHide=this.toHide.add(this.containers);}this.showErrors();return result;},showErrors:function(errors){if(errors){$.extend(this.errorMap,errors);this.errorList=[];for(var name in errors){this.errorList.push({message:errors[name],element:this.findByName(name)[0]});}this.successList=$.grep(this.successList,function(element){return!(element.name in errors);});}this.settings.showErrors?this.settings.showErrors.call(this,this.errorMap,this.errorList):this.defaultShowErrors();},resetForm:function(){if($.fn.resetForm)$(this.currentForm).resetForm();this.submitted={};this.prepareForm();this.hideErrors();this.elements().removeClass(this.settings.errorClass);},numberOfInvalids:function(){return this.objectLength(this.invalid);},objectLength:function(obj){var count=0;for(var i in obj)count++;return count;},hideErrors:function(){this.addWrapper(this.toHide).hide();},valid:function(){return this.size()==0;},size:function(){return this.errorList.length;},focusInvalid:function(){if(this.settings.focusInvalid){try{$(this.findLastActive()||this.errorList.length&&this.errorList[0].element||[]).filter(":visible").focus();}catch(e){}}},findLastActive:function(){var lastActive=this.lastActive;return lastActive&&$.grep(this.errorList,function(n){return n.element.name==lastActive.name;}).length==1&&lastActive;},elements:function(){var validator=this,rulesCache={};return $([]).add(this.currentForm.elements).filter(":input").not(":submit, :reset, :image, [disabled]").not(this.settings.ignore).filter(function(){!this.name&&validator.settings.debug&&window.console&&console.error("%o has no name assigned",this);if(this.name in rulesCache||!validator.objectLength($(this).rules()))return false;rulesCache[this.name]=true;return true;});},clean:function(selector){return $(selector)[0];},errors:function(){return $(this.settings.errorElement+"."+this.settings.errorClass,this.errorContext);},reset:function(){this.successList=[];this.errorList=[];this.errorMap={};this.toShow=$([]);this.toHide=$([]);this.formSubmitted=false;this.currentElements=$([]);},prepareForm:function(){this.reset();this.toHide=this.errors().add(this.containers);},prepareElement:function(element){this.reset();this.toHide=this.errorsFor(element);},check:function(element){element=this.clean(element);if(this.checkable(element)){element=this.findByName(element.name)[0];}var rules=$(element).rules();var dependencyMismatch=false;for(method in rules){var rule={method:method,parameters:rules[method]};try{var result=$.validator.methods[method].call(this,element.value.replace(/\r/g,""),element,rule.parameters);if(result=="dependency-mismatch"){dependencyMismatch=true;continue;}dependencyMismatch=false;if(result=="pending"){this.toHide=this.toHide.not(this.errorsFor(element));return;}if(!result){this.formatAndAdd(element,rule);return false;}}catch(e){this.settings.debug&&window.console&&console.log("exception occured when checking element "+element.id ++", check the '"+rule.method+"' method");throw e;}}if(dependencyMismatch)return;if(this.objectLength(rules))this.successList.push(element);return true;},customMetaMessage:function(element,method){if(!$.metadata)return;var meta=this.settings.meta?$(element).metadata()[this.settings.meta]:$(element).metadata();return meta&&meta.messages&&meta.messages[method];},customMessage:function(name,method){var m=this.settings.messages[name];return m&&(m.constructor==String?m:m[method]);},findDefined:function(){for(var i=0;iWarning: No message defined for "+element.name+"");},formatAndAdd:function(element,rule){var message=this.defaultMessage(element,rule.method);if(typeof message=="function")message=message.call(this,rule.parameters,element);this.errorList.push({message:message,element:element});this.errorMap[element.name]=message;this.submitted[element.name]=message;},addWrapper:function(toToggle){if(this.settings.wrapper)toToggle=toToggle.add(toToggle.parent(this.settings.wrapper));return toToggle;},defaultShowErrors:function(){for(var i=0;this.errorList[i];i++){var error=this.errorList[i];this.settings.highlight&&this.settings.highlight.call(this,error.element,this.settings.errorClass,this.settings.validClass);this.showLabel(error.element,error.message);}if(this.errorList.length){this.toShow=this.toShow.add(this.containers);}if(this.settings.success){for(var i=0;this.successList[i];i++){this.showLabel(this.successList[i]);}}if(this.settings.unhighlight){for(var i=0,elements=this.validElements();elements[i];i++){this.settings.unhighlight.call(this,elements[i],this.settings.errorClass,this.settings.validClass);}}this.toHide=this.toHide.not(this.toShow);this.hideErrors();this.addWrapper(this.toShow).show();},validElements:function(){return this.currentElements.not(this.invalidElements());},invalidElements:function(){return $(this.errorList).map(function(){return this.element;});},showLabel:function(element,message){var label=this.errorsFor(element);if(label.length){label.removeClass().addClass(this.settings.errorClass);label.attr("generated")&&label.html(message);}else{label=$("<"+this.settings.errorElement+"/>").attr({"for":this.idOrName(element),generated:true}).addClass(this.settings.errorClass).html(message||"");if(this.settings.wrapper){label=label.hide().show().wrap("<"+this.settings.wrapper+"/>").parent();}if(!this.labelContainer.append(label).length)this.settings.errorPlacement?this.settings.errorPlacement(label,$(element)):label.insertAfter(element);}if(!message&&this.settings.success){label.text("");typeof this.settings.success=="string"?label.addClass(this.settings.success):this.settings.success(label);}this.toShow=this.toShow.add(label);},errorsFor:function(element){return this.errors().filter("[for='"+this.idOrName(element)+"']");},idOrName:function(element){return this.groups[element.name]||(this.checkable(element)?element.name:element.id||element.name);},checkable:function(element){return/radio|checkbox/i.test(element.type);},findByName:function(name){var form=this.currentForm;return $(document.getElementsByName(name)).map(function(index,element){return element.form==form&&element.name==name&&element||null;});},getLength:function(value,element){switch(element.nodeName.toLowerCase()){case'select':return $("option:selected",element).length;case'input':if(this.checkable(element))return this.findByName(element.name).filter(':checked').length;}return value.length;},depend:function(param,element){return this.dependTypes[typeof param]?this.dependTypes[typeof param](param,element):true;},dependTypes:{"boolean":function(param,element){return param;},"string":function(param,element){return!!$(param,element.form).length;},"function":function(param,element){return param(element);}},optional:function(element){return!$.validator.methods.required.call(this,$.trim(element.value),element)&&"dependency-mismatch";},startRequest:function(element){if(!this.pending[element.name]){this.pendingRequest++;this.pending[element.name]=true;}},stopRequest:function(element,valid){this.pendingRequest--;if(this.pendingRequest<0)this.pendingRequest=0;delete this.pending[element.name];if(valid&&this.pendingRequest==0&&this.formSubmitted&&this.form()){$(this.currentForm).submit();}else if(!valid&&this.pendingRequest==0&&this.formSubmitted){$(this.currentForm).triggerHandler("invalid-form",[this]);}},previousValue:function(element){return $.data(element,"previousValue")||$.data(element,"previousValue",previous={old:null,valid:true,message:this.defaultMessage(element,"remote")});}},classRuleSettings:{required:{required:true},email:{email:true},url:{url:true},date:{date:true},dateISO:{dateISO:true},dateDE:{dateDE:true},number:{number:true},numberDE:{numberDE:true},digits:{digits:true},creditcard:{creditcard:true}},addClassRules:function(className,rules){className.constructor==String?this.classRuleSettings[className]=rules:$.extend(this.classRuleSettings,className);},classRules:function(element){var rules={};var classes=$(element).attr('class');classes&&$.each(classes.split(' '),function(){if(this in $.validator.classRuleSettings){$.extend(rules,$.validator.classRuleSettings[this]);}});return rules;},attributeRules:function(element){var rules={};var $element=$(element);for(method in $.validator.methods){var value=$element.attr(method);if(value){rules[method]=value;}}if(rules.maxlength&&/-1|2147483647|524288/.test(rules.maxlength)){delete rules.maxlength;}return rules;},metadataRules:function(element){if(!$.metadata)return{};var meta=$.data(element.form,'validator').settings.meta;return meta?$(element).metadata()[meta]:$(element).metadata();},staticRules:function(element){var rules={};var validator=$.data(element.form,'validator');if(validator.settings.rules){rules=$.validator.normalizeRule(validator.settings.rules[element.name])||{};}return rules;},normalizeRules:function(rules,element){$.each(rules,function(prop,val){if(val===false){delete rules[prop];return;}if(val.param||val.depends){var keepRule=true;switch(typeof val.depends){case"string":keepRule=!!$(val.depends,element.form).length;break;case"function":keepRule=val.depends.call(element,element);break;}if(keepRule){rules[prop]=val.param!==undefined?val.param:true;}else{delete rules[prop];}}});$.each(rules,function(rule,parameter){rules[rule]=$.isFunction(parameter)?parameter(element):parameter;});$.each(['minlength','maxlength','min','max'],function(){if(rules[this]){rules[this]=Number(rules[this]);}});$.each(['rangelength','range'],function(){if(rules[this]){rules[this]=[Number(rules[this][0]),Number(rules[this][1])];}});if($.validator.autoCreateRanges){if(rules.min&&rules.max){rules.range=[rules.min,rules.max];delete rules.min;delete rules.max;}if(rules.minlength&&rules.maxlength){rules.rangelength=[rules.minlength,rules.maxlength];delete rules.minlength;delete rules.maxlength;}}if(rules.messages){delete rules.messages}return rules;},normalizeRule:function(data){if(typeof data=="string"){var transformed={};$.each(data.split(/\s/),function(){transformed[this]=true;});data=transformed;}return data;},addMethod:function(name,method,message){$.validator.methods[name]=method;$.validator.messages[name]=message||$.validator.messages[name];if(method.length<3){$.validator.addClassRules(name,$.validator.normalizeRule(name));}},methods:{required:function(value,element,param){if(!this.depend(param,element))return"dependency-mismatch";switch(element.nodeName.toLowerCase()){case'select':var options=$("option:selected",element);return options.length>0&&(element.type=="select-multiple"||($.browser.msie&&!(options[0].attributes['value'].specified)?options[0].text:options[0].value).length>0);case'input':if(this.checkable(element))return this.getLength(value,element)>0;default:return $.trim(value).length>0;}},remote:function(value,element,param){if(this.optional(element))return"dependency-mismatch";var previous=this.previousValue(element);if(!this.settings.messages[element.name])this.settings.messages[element.name]={};this.settings.messages[element.name].remote=typeof previous.message=="function"?previous.message(value):previous.message;param=typeof param=="string"&&{url:param}||param;if(previous.old!==value){previous.old=value;var validator=this;this.startRequest(element);var data={};data[element.name]=value;$.ajax($.extend(true,{url:param,mode:"abort",port:"validate"+element.name,dataType:"json",data:data,success:function(response){var valid=response===true;if(valid){var submitted=validator.formSubmitted;validator.prepareElement(element);validator.formSubmitted=submitted;validator.successList.push(element);validator.showErrors();}else{var errors={};errors[element.name]=previous.message=response||validator.defaultMessage(element,"remote");validator.showErrors(errors);}previous.valid=valid;validator.stopRequest(element,valid);}},param));return"pending";}else if(this.pending[element.name]){return"pending";}return previous.valid;},minlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)>=param;},maxlength:function(value,element,param){return this.optional(element)||this.getLength($.trim(value),element)<=param;},rangelength:function(value,element,param){var length=this.getLength($.trim(value),element);return this.optional(element)||(length>=param[0]&&length<=param[1]);},min:function(value,element,param){return this.optional(element)||value>=param;},max:function(value,element,param){return this.optional(element)||value<=param;},range:function(value,element,param){return this.optional(element)||(value>=param[0]&&value<=param[1]);},email:function(value,element){return this.optional(element)||/^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value);},url:function(value,element){return this.optional(element)||/^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);},date:function(value,element){return this.optional(element)||!/Invalid|NaN/.test(new Date(value));},dateISO:function(value,element){return this.optional(element)||/^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value);},dateDE:function(value,element){return this.optional(element)||/^\d\d?\.\d\d?\.\d\d\d?\d?$/.test(value);},number:function(value,element){return this.optional(element)||/^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value);},numberDE:function(value,element){return this.optional(element)||/^-?(?:\d+|\d{1,3}(?:\.\d{3})+)(?:,\d+)?$/.test(value);},digits:function(value,element){return this.optional(element)||/^\d+$/.test(value);},creditcard:function(value,element){if(this.optional(element))return"dependency-mismatch";if(/[^0-9-]+/.test(value))return false;var nCheck=0,nDigit=0,bEven=false;value=value.replace(/\D/g,"");for(n=value.length-1;n>=0;n--){var cDigit=value.charAt(n);var nDigit=parseInt(cDigit,10);if(bEven){if((nDigit*=2)>9)nDigit-=9;}nCheck+=nDigit;bEven=!bEven;}return(nCheck%10)==0;},accept:function(value,element,param){param=typeof param=="string"?param.replace(/,/g,'|'):"png|jpe?g|gif";return this.optional(element)||value.match(new RegExp(".("+param+")$","i"));},equalTo:function(value,element,param){return value==$(param).val();}}});$.format=$.validator.format;})(jQuery);;(function($){var ajax=$.ajax;var pendingRequests={};$.ajax=function(settings){settings=$.extend(settings,$.extend({},$.ajaxSettings,settings));var port=settings.port;if(settings.mode=="abort"){if(pendingRequests[port]){pendingRequests[port].abort();}return(pendingRequests[port]=ajax.apply(this,arguments));}return ajax.apply(this,arguments);};})(jQuery);;(function($){$.each({focus:'focusin',blur:'focusout'},function(original,fix){$.event.special[fix]={setup:function(){if($.browser.msie)return false;this.addEventListener(original,$.event.special[fix].handler,true);},teardown:function(){if($.browser.msie)return false;this.removeEventListener(original,$.event.special[fix].handler,true);},handler:function(e){arguments[0]=$.event.fix(e);arguments[0].type=fix;return $.event.handle.apply(this,arguments);}};});$.extend($.fn,{delegate:function(type,delegate,handler){return this.bind(type,function(event){var target=$(event.target);if(target.is(delegate)){return handler.apply(target,arguments);}});},triggerEvent:function(type,target){return this.triggerHandler(type,[$.event.fix({type:type,target:target})]);}})})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jrails.autocomplete.js b/spec/test_app/public/javascripts/jrails.autocomplete.js new file mode 100644 index 0000000..a2cddc2 --- /dev/null +++ b/spec/test_app/public/javascripts/jrails.autocomplete.js @@ -0,0 +1,274 @@ +(function($) { + function stopEvent(e) { + e.preventDefault(); + e.stopPropagation(); + e.stopped = true; + } + + function getFirstDifferencePos(newS, oldS) { + var boundary = Math.min(newS.length, oldS.length); + for (var index = 0; index < boundary; ++index) + if (newS[index] != oldS[index]) return index; + return boundary; + } + + var AutoComplete = function(element, update, url, options) { + var autocomplete = this; + + this.element = element; + this.url = url; + this.update = update; + this.hasFocus = false; + this.changed = false; + this.active = false; + this.index = 0; + this.entryCount = 0; + this.oldElementValue = this.element.value; + this.observer = null; + this.options = $.extend({ + paramName: this.element.name, + type: 'GET', + tokens: [], + frequency: 0.4, + minChars: 1, + onShow: function(element, update) { + if (!update.style.position || update.style.position == 'absolute') { + var position = $(element).position(); + $(update).css({ + position: 'absolute', + left: position.left + 'px', + top: $(element).outerHeight() + position.top + 'px', + width: $(element).outerWidth() + 'px' + }); + } + $(update).fadeIn(); + }, + onHide: function(element, update) { + $(update).fadeOut(); + } + }, options); + + if (typeof(this.options.tokens) == 'string') { + this.options.tokens = new Array(this.options.tokens); + } + if (!$.inArray("\n", this.options.tokens)) { + this.options.tokens.push("\n"); + } + + $(this.update).hide(); + $(this.element).attr('autocomplete', 'off') + .blur(function(e) { autocomplete.onBlur(e); }) + .keypress(function(e) { autocomplete.onKeyPress(e); }); + } + $.extend(AutoComplete.prototype, { + show: function() { + if ($(this.update).not(':visible')) this.options.onShow(this.element, this.update); + }, + hide: function() { + this.stopIndicator(); + if ($(this.update).is(':visible')) this.options.onHide(this.element, this.update); + }, + startIndicator: function() { + if (this.options.indicator) $('#' + this.options.indicator).show(); + }, + stopIndicator: function() { + if (this.options.indicator) $('#' + this.options.indicator).hide(); + }, + onKeyPress: function(e) { + var autocomplete = this; + + if (this.active) { + switch (e.keyCode) { + case 9: // tab + case 13: // return + this.selectEntry(); + stopEvent(e); + case 27: // esc + this.hide(); + this.active = false; + stopEvent(e); + case 37: // left + case 39: // right + return; + case 38: // up + this.markPrevious(); + this.render(); + stopEvent(e); + return; + case 40: // down + this.markNext(); + this.render(); + stopEvent(e); + return; + } + } + else if (e.keyCode == 9 || e.keyCode == 13) return; + + this.changed = this.hasFocus = true; + if (this.observer) clearTimeout(this.observer); + this.observer = setTimeout(function() { autocomplete.onObserverEvent(); }, this.frequency * 1000); + }, + activate: function() { + this.changed = false; + this.hasFocus = true; + this.getUpdatedChoices(); + }, + onHover: function(e) { + if (this.index != e.target.autocompleteIndex) { + this.index = e.target.autocompleteIndex; + this.render(); + } + stopEvent(e); + }, + onClick: function(e) { + this.index = e.target.autocompleteIndex; + this.selectEntry(); + this.hide(); + }, + onBlur: function(e) { + var autocomplete = this; + setTimeout(function() { autocomplete.hide(); }, 250); + this.active = this.hasFocus = false; + }, + render: function() { + if (this.entryCount > 0) { + for (var i = 0; i < this.entryCount; ++i) { + $(this.getEntry(i))[this.index == i ? 'addClass' : 'removeClass']('selected'); + } + if (this.hasFocus) { + this.show(); + this.active = true; + } + } + else { + this.active = false; + this.hide(); + } + }, + markPrevious: function() { + if (this.index > 0) --this.index; + else this.index = this.entryCount - 1; + }, + markNext: function() { + if (this.index < this.entryCount - 1) ++this.index; + else this.index = 0; + }, + getEntry: function(i) { + return $(this.update.firstChild).children('li').get(i); + }, + getCurrentEntry: function() { + return this.getEntry(this.index); + }, + selectEntry: function() { + this.active = false; + this.updateElement(this.getCurrentEntry()); + }, + updateElement: function(element) { + if (this.options.updateElement) { + this.options.updateElement(element); + return; + } + + var value = $.trim(this.options.select ? + $('.' + this.options.select, element).text() : + $(element).text()); + + var bounds = this.getTokenBounds(); + if (bounds[0] != -1) { + var newValue = this.element.value.substr(0, bounds[0]); + var whitespace = this.element.value.substr(bounds[0]).match(/^\s+/); + if (whitespace) newValue += whitespace[0]; + this.element.value = newValue + value + this.element.value.substr(bounds[1]); + } + else { + this.element.value = value; + } + + this.oldElementValue = $(this.element).focus().val(); + + if (this.options.afterUpdateElement) this.options.afterUpdateElement(this.element, element); + }, + updateChoices: function(choices) { + if (!this.changed && this.hasFocus) { + $(this.update).html($.trim(choices)); + var i = 0, autocomplete = this; + this.entryCount = $(this.update.firstChild).children('li').each(function() { + this.autocompleteIndex = i++; + autocomplete.addObservers(this); + }).length; + } + + this.stopIndicator(); + this.index = 0; + + if (this.entryCount == 1 && this.options.autoSelect) { + this.selectEntry(); + this.hide(); + } + else { + this.render(); + } + }, + addObservers: function(element) { + var autocomplete = this; + $(element) + .mouseover(function(e) { autocomplete.onHover(e); }) + .click(function(e) { autocomplete.onClick(e); }); + }, + onObserverEvent: function() { + this.changed = false; + this.tokenBounds = null; + if (this.getToken().length >= this.options.minChars) { + this.getUpdatedChoices(); + } + else { + this.active = false; + this.hide(); + } + this.oldElementValue = this.element.value; + }, + getToken: function() { + var bounds = this.getTokenBounds(); + return $.trim(this.element.value.substring(bounds[0], bounds[1])); + }, + getTokenBounds: function() { + if (null != this.tokenBounds) return this.tokenBounds; + var value = $.trim(this.element.value); + if (!value.length) return [-1, 0]; + var diff = getFirstDifferencePos(value, this.oldElementValue); + var offset = (diff == this.oldElementValue.length ? 1 : 0); + var prevTokenPos = -1, nextTokenPos = value.length; + for (var tp = null, index = 0, l = this.options.tokens.length; index < l; ++index) { + tp = value.lastIndexOf(this.options.tokens[index], diff + offset - 1); + if (tp > prevTokenPos) prevTokenPos = tp; + tp = value.indexOf(this.options.tokens[index], diff + offset); + if (-1 != tp && tp < nextTokenPos) nextTokenPos = tp; + } + return (this.tokenBounds = [prevTokenPos + 1, nextTokenPos]); + }, + getUpdatedChoices: function() { + this.startIndicator(); + + var autocomplete = this, entry = encodeURIComponent(this.options.paramName) + '=' + encodeURIComponent(this.getToken()); + this.options.data = this.options.callback ? this.options.callback(this.element, entry) : entry; + + if (this.options.defaultParams) this.options.data += '&' + this.options.defaultParams; + var ajaxOptions = $.extend({}, this.options, { + url: this.url, + success: function(data, status) { + autocomplete.updateChoices(data); + } + }); + $.ajax(ajaxOptions); + } + }); + + $.fn.autocomplete = function(options) { + var update = $('#' + options.update).get(0), url = options.url; + options.update = options.url = undefined; + this.filter(':text').each(function() { + new AutoComplete(this, update, url, options); + }); + return this; + } +})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jrails.js b/spec/test_app/public/javascripts/jrails.js new file mode 100644 index 0000000..39aa4ec --- /dev/null +++ b/spec/test_app/public/javascripts/jrails.js @@ -0,0 +1 @@ +(function($){$.ajaxSettings.accepts._default="text/javascript, text/html, application/xml, text/xml, */*"})(jQuery);(function($){$.fn.reset=function(){return this.each(function(){if(typeof this.reset=="function"||(typeof this.reset=="object"&&!this.reset.nodeType)){this.reset()}})};$.fn.enable=function(){return this.each(function(){this.disabled=false})};$.fn.disable=function(){return this.each(function(){this.disabled=true})}})(jQuery);(function($){$.extend({fieldEvent:function(el,obs){var field=el[0]||el,e="change";if(field.type=="radio"||field.type=="checkbox"){e="click"}else{if(obs&&(field.type=="text"||field.type=="textarea"||field.type=="password")){e="keyup"}}return e}});$.fn.extend({delayedObserver:function(delay,callback){var el=$(this);if(typeof window.delayedObserverStack=="undefined"){window.delayedObserverStack=[]}if(typeof window.delayedObserverCallback=="undefined"){window.delayedObserverCallback=function(stackPos){var observed=window.delayedObserverStack[stackPos];if(observed.timer){clearTimeout(observed.timer)}observed.timer=setTimeout(function(){observed.timer=null;observed.callback(observed.obj,observed.obj.formVal())},observed.delay*1000);observed.oldVal=observed.obj.formVal()}}window.delayedObserverStack.push({obj:el,timer:null,delay:delay,oldVal:el.formVal(),callback:callback});var stackPos=window.delayedObserverStack.length-1;if(el[0].tagName=="FORM"){$(":input",el).each(function(){var field=$(this);field.bind($.fieldEvent(field,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})})}else{el.bind($.fieldEvent(el,delay),function(){var observed=window.delayedObserverStack[stackPos];if(observed.obj.formVal()==observed.oldVal){return}else{window.delayedObserverCallback(stackPos)}})}},formVal:function(){var el=this[0];if(el.tagName=="FORM"){return this.serialize()}if(el.type=="checkbox"||el.type=="radio"){return this.filter("input:checked").val()||""}else{return this.val()}}})})(jQuery);(function($){$.fn.extend({visualEffect:function(o,options){if(options){speed=options.duration*1000}else{speed=null}e=o.replace(/\_(.)/g,function(m,l){return l.toUpperCase()});return eval("$(this)."+e+"("+speed+")")},appear:function(speed,callback){return this.fadeIn(speed,callback)},blindDown:function(speed,callback){return this.show("blind",{direction:"vertical"},speed,callback)},blindUp:function(speed,callback){return this.hide("blind",{direction:"vertical"},speed,callback)},blindRight:function(speed,callback){return this.show("blind",{direction:"horizontal"},speed,callback)},blindLeft:function(speed,callback){this.hide("blind",{direction:"horizontal"},speed,callback);return this},dropOut:function(speed,callback){return this.hide("drop",{direction:"down"},speed,callback)},dropIn:function(speed,callback){return this.show("drop",{direction:"up"},speed,callback)},fade:function(speed,callback){return this.fadeOut(speed,callback)},fadeToggle:function(speed,callback){return this.animate({opacity:"toggle"},speed,callback)},fold:function(speed,callback){return this.hide("fold",{},speed,callback)},foldOut:function(speed,callback){return this.show("fold",{},speed,callback)},grow:function(speed,callback){return this.show("scale",{},speed,callback)},highlight:function(speed,callback){return this.show("highlight",{},speed,callback)},puff:function(speed,callback){return this.hide("puff",{},speed,callback)},pulsate:function(speed,callback){return this.show("pulsate",{},speed,callback)},shake:function(speed,callback){return this.show("shake",{},speed,callback)},shrink:function(speed,callback){return this.hide("scale",{},speed,callback)},squish:function(speed,callback){return this.hide("scale",{origin:["top","left"]},speed,callback)},slideUp:function(speed,callback){return this.hide("slide",{direction:"up"},speed,callback)},slideDown:function(speed,callback){return this.show("slide",{direction:"up"},speed,callback)},switchOff:function(speed,callback){return this.hide("clip",{},speed,callback)},switchOn:function(speed,callback){return this.show("clip",{},speed,callback)}})})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jsTree/jquery.tree.js b/spec/test_app/public/javascripts/jsTree/jquery.tree.js new file mode 100755 index 0000000..0cb25d3 --- /dev/null +++ b/spec/test_app/public/javascripts/jsTree/jquery.tree.js @@ -0,0 +1,2058 @@ +/* + * jsTree 0.9.9a + * http://jstree.com/ + * + * Copyright (c) 2009 Ivan Bozhanov (vakata.com) + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + * + * Date: 2009-10-06 + * + */ + +(function($) { + // jQuery plugin + $.tree = { + datastores : { }, + plugins : { }, + defaults : { + data : { + async : false, // Are async requests used to load open_branch contents + type : "html", // One of included datastores + opts : { method: "GET", url: false } // Options passed to datastore + }, + selected : false, // FALSE or STRING or ARRAY + opened : [], // ARRAY OF INITIALLY OPENED NODES + languages : [], // ARRAY of string values (which will be used as CSS classes - so they must be valid) + ui : { + dots : true, // BOOL - dots or no dots + animation : 0, // INT - duration of open/close animations in miliseconds + scroll_spd : 4, + theme_path : false, // Path to the theme CSS file - if set to false and theme_name is not false - will lookup jstree-path-here/themes/theme-name-here/style.css + theme_name : "default",// if set to false no theme will be loaded + selected_parent_close : "select_parent", // false, "deselect", "select_parent" + selected_delete : "select_previous" // false, "select_previous" + }, + types : { + "default" : { + clickable : true, // can be function + renameable : true, // can be function + deletable : true, // can be function + creatable : true, // can be function + draggable : true, // can be function + max_children : -1, // -1 - not set, 0 - no children, 1 - one child, etc // can be function + max_depth : -1, // -1 - not set, 0 - no children, 1 - one level of children, etc // can be function + valid_children : "all", // all, none, array of values // can be function + icon : { + image : false, + position : false + } + } + }, + rules : { + multiple : false, // FALSE | CTRL | ON - multiple selection off/ with or without holding Ctrl + multitree : "none", // all, none, array of tree IDs to accept from + type_attr : "rel", // STRING attribute name (where is the type stored as string) + createat : "bottom", // STRING (top or bottom) new nodes get inserted at top or bottom + drag_copy : "ctrl", // FALSE | CTRL | ON - drag to copy off/ with or without holding Ctrl + drag_button : "left", // left, right or both + use_max_children : true, + use_max_depth : true, + + max_children: -1, + max_depth : -1, + valid_children : "all" + }, + lang : { + new_node : "New folder", + loading : "Loading ..." + }, + callback : { + beforechange: function(NODE,TREE_OBJ) { return true }, + beforeopen : function(NODE,TREE_OBJ) { return true }, + beforeclose : function(NODE,TREE_OBJ) { return true }, + beforemove : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, + beforecreate: function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true }, + beforerename: function(NODE,LANG,TREE_OBJ) { return true }, + beforedelete: function(NODE,TREE_OBJ) { return true }, + beforedata : function(NODE,TREE_OBJ) { return { id : $(NODE).attr("id") || 0 } }, // PARAMETERS PASSED TO SERVER + ondata : function(DATA,TREE_OBJ) { return DATA; }, // modify data before parsing it + onparse : function(STR,TREE_OBJ) { return STR; }, // modify string before visualizing it + onhover : function(NODE,TREE_OBJ) { }, // node hovered + onselect : function(NODE,TREE_OBJ) { }, // node selected + ondeselect : function(NODE,TREE_OBJ) { }, // node deselected + onchange : function(NODE,TREE_OBJ) { }, // focus changed + onrename : function(NODE,TREE_OBJ,RB) { }, // node renamed + onmove : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // move completed + oncopy : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // copy completed + oncreate : function(NODE,REF_NODE,TYPE,TREE_OBJ,RB) { }, // node created + ondelete : function(NODE,TREE_OBJ,RB) { }, // node deleted + onopen : function(NODE,TREE_OBJ) { }, // node opened + onopen_all : function(TREE_OBJ) { }, // all nodes opened + onclose_all : function(TREE_OBJ) { }, // all nodes closed + onclose : function(NODE,TREE_OBJ) { }, // node closed + error : function(TEXT,TREE_OBJ) { }, // error occured + ondblclk : function(NODE,TREE_OBJ) { TREE_OBJ.toggle_branch.call(TREE_OBJ, NODE); TREE_OBJ.select_branch.call(TREE_OBJ, NODE); }, + onrgtclk : function(NODE,TREE_OBJ,EV) { }, // right click - to prevent use: EV.preventDefault(); EV.stopPropagation(); return false + onload : function(TREE_OBJ) { }, + oninit : function(TREE_OBJ) { }, + onfocus : function(TREE_OBJ) { }, + ondestroy : function(TREE_OBJ) { }, + onsearch : function(NODES, TREE_OBJ) { NODES.addClass("search"); }, + ondrop : function(NODE,REF_NODE,TYPE,TREE_OBJ) { }, + check : function(RULE,NODE,VALUE,TREE_OBJ) { return VALUE; }, + check_move : function(NODE,REF_NODE,TYPE,TREE_OBJ) { return true; } + }, + plugins : { } + }, + + create : function () { return new tree_component(); }, + focused : function () { return tree_component.inst[tree_component.focused]; }, + reference : function (obj) { + var o = $(obj); + if(!o.size()) o = $("#" + obj); + if(!o.size()) return null; + o = (o.is(".tree")) ? o.attr("id") : o.parents(".tree:eq(0)").attr("id"); + return tree_component.inst[o] || null; + }, + rollback : function (data) { + for(var i in data) { + if(!data.hasOwnProperty(i)) continue; + var tmp = tree_component.inst[i]; + var lock = !tmp.locked; + + // if not locked - lock the tree + if(lock) tmp.lock(true); + // Cancel ongoing rename + tmp.inp = false; + tmp.container.html(data[i].html).find(".dragged").removeClass("dragged").end().find(".hover").removeClass("hover"); + + if(data[i].selected) { + tmp.selected = $("#" + data[i].selected); + tmp.selected_arr = []; + tmp.container + .find("a.clicked").each( function () { + tmp.selected_arr.push(tmp.get_node(this)); + }); + } + // if this function set the lock - unlock + if(lock) tmp.lock(false); + + delete lock; + delete tmp; + } + }, + drop_mode : function (opts) { + opts = $.extend(opts, { show : false, type : "default", str : "Foreign node" }); + tree_component.drag_drop.foreign = true; + tree_component.drag_drop.isdown = true; + tree_component.drag_drop.moving = true; + tree_component.drag_drop.appended = false; + tree_component.drag_drop.f_type = opts.type; + tree_component.drag_drop.f_data = opts; + + + if(!opts.show) { + tree_component.drag_drop.drag_help = false; + tree_component.drag_drop.drag_node = false; + } + else { + tree_component.drag_drop.drag_help = $(""); + tree_component.drag_drop.drag_node = tree_component.drag_drop.drag_help.find("li:eq(0)"); + } + if($.tree.drag_start !== false) $.tree.drag_start.call(null, false); + }, + drag_start : false, + drag : false, + drag_end : false + }; + $.fn.tree = function (opts) { + return this.each(function() { + var conf = $.extend({},opts); + if(tree_component.inst && tree_component.inst[$(this).attr('id')]) tree_component.inst[$(this).attr('id')].destroy(); + if(conf !== false) new tree_component().init(this, conf); + }); + }; + + // core + function tree_component () { + return { + cntr : ++tree_component.cntr, + settings : $.extend({},$.tree.defaults), + + init : function(elem, conf) { + var _this = this; + this.container = $(elem); + if(this.container.size == 0) return false; + tree_component.inst[this.cntr] = this; + if(!this.container.attr("id")) this.container.attr("id","jstree_" + this.cntr); + tree_component.inst[this.container.attr("id")] = tree_component.inst[this.cntr]; + tree_component.focused = this.cntr; + this.settings = $.extend(true, {}, this.settings, conf); + + // DEAL WITH LANGUAGE VERSIONS + if(this.settings.languages && this.settings.languages.length) { + this.current_lang = this.settings.languages[0]; + var st = false; + var id = "#" + this.container.attr("id"); + for(var ln = 0; ln < this.settings.languages.length; ln++) { + st = tree_component.add_css(id + " ." + this.settings.languages[ln]); + if(st !== false) st.style.display = (this.settings.languages[ln] == this.current_lang) ? "" : "none"; + } + } + else this.current_lang = false; + // THEMES + this.container.addClass("tree"); + if(this.settings.ui.theme_name !== false) { + if(this.settings.ui.theme_path === false) { + $("script").each(function () { + if(this.src.toString().match(/jquery\.tree.*?js$/)) { _this.settings.ui.theme_path = this.src.toString().replace(/jquery\.tree.*?js$/, "") + "themes/" + _this.settings.ui.theme_name + "/style.css"; return false; } + }); + } + if(this.settings.ui.theme_path != "" && $.inArray(this.settings.ui.theme_path, tree_component.themes) == -1) { + tree_component.add_sheet({ url : this.settings.ui.theme_path }); + tree_component.themes.push(this.settings.ui.theme_path); + } + this.container.addClass("tree-" + this.settings.ui.theme_name); + } + // TYPE ICONS + var type_icons = ""; + for(var t in this.settings.types) { + if(!this.settings.types.hasOwnProperty(t)) continue; + if(!this.settings.types[t].icon) continue; + if( this.settings.types[t].icon.image || this.settings.types[t].icon.position) { + if(t == "default") type_icons += "#" + this.container.attr("id") + " li > a ins { "; + else type_icons += "#" + this.container.attr("id") + " li[rel=" + t + "] > a ins { "; + if(this.settings.types[t].icon.image) type_icons += " background-image:url(" + this.settings.types[t].icon.image + "); "; + if(this.settings.types[t].icon.position) type_icons += " background-position:" + this.settings.types[t].icon.position + "; "; + type_icons += "} "; + } + } + if(type_icons != "") tree_component.add_sheet({ str : type_icons }); + + if(this.settings.rules.multiple) this.selected_arr = []; + this.offset = false; + this.hovered = false; + this.locked = false; + + if(tree_component.drag_drop.marker === false) tree_component.drag_drop.marker = $("
          ").attr({ id : "jstree-marker" }).hide().appendTo("body"); + this.callback("oninit", [this]); + this.refresh(); + this.attach_events(); + this.focus(); + }, + refresh : function (obj) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + if(obj && !this.settings.data.async) obj = false; + this.is_partial_refresh = obj ? true : false; + + // SAVE OPENED + this.opened = Array(); + if(this.settings.opened != false) { + $.each(this.settings.opened, function (i, item) { + if(this.replace(/^#/,"").length > 0) { _this.opened.push("#" + this.replace(/^#/,"")); } + }); + this.settings.opened = false; + } + else { + this.container.find("li.open").each(function (i) { if(this.id) { _this.opened.push("#" + this.id); } }); + } + + // SAVE SELECTED + if(this.selected) { + this.settings.selected = Array(); + if(obj) { + $(obj).find("li:has(a.clicked)").each(function () { + if(this.id) _this.settings.selected.push("#" + this.id); + }); + } + else { + if(this.selected_arr) { + $.each(this.selected_arr, function () { + if(this.attr("id")) _this.settings.selected.push("#" + this.attr("id")); + }); + } + else { + if(this.selected.attr("id")) this.settings.selected.push("#" + this.selected.attr("id")); + } + } + } + else if(this.settings.selected !== false) { + var tmp = Array(); + if((typeof this.settings.selected).toLowerCase() == "object") { + $.each(this.settings.selected, function () { + if(this.replace(/^#/,"").length > 0) tmp.push("#" + this.replace(/^#/,"")); + }); + } + else { + if(this.settings.selected.replace(/^#/,"").length > 0) tmp.push("#" + this.settings.selected.replace(/^#/,"")); + } + this.settings.selected = tmp; + } + + if(obj && this.settings.data.async) { + this.opened = Array(); + obj = this.get_node(obj); + obj.find("li.open").each(function (i) { _this.opened.push("#" + this.id); }); + if(obj.hasClass("open")) obj.removeClass("open").addClass("closed"); + if(obj.hasClass("leaf")) obj.removeClass("leaf"); + obj.children("ul:eq(0)").html(""); + return this.open_branch(obj, true, function () { _this.reselect.apply(_this); }); + } + + var _this = this; + var _datastore = new $.tree.datastores[this.settings.data.type](); + if(this.container.children("ul").size() == 0) { + this.container.html(""); + } + _datastore.load(this.callback("beforedata",[false,this]),this,this.settings.data.opts,function(data) { + data = _this.callback("ondata",[data, _this]); + _datastore.parse(data,_this,_this.settings.data.opts,function(str) { + str = _this.callback("onparse", [str, _this]); + _this.container.empty().append($("
            ").html(str)); + _this.container.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed"); + _this.container.find("li").not(".open").not(".closed").addClass("leaf"); + _this.reselect(); + }); + }); + }, + reselect : function (is_callback) { + var _this = this; + + if(!is_callback) this.cl_count = 0; + else this.cl_count --; + // REOPEN BRANCHES + if(this.opened && this.opened.length) { + var opn = false; + for(var j = 0; this.opened && j < this.opened.length; j++) { + if(this.settings.data.async) { + var tmp = this.get_node(this.opened[j]); + if(tmp.size() && tmp.hasClass("closed") > 0) { + opn = true; + var tmp = this.opened[j].toString().replace('/','\\/'); + delete this.opened[j]; + this.open_branch(tmp, true, function () { _this.reselect.apply(_this, [true]); } ); + this.cl_count ++; + } + } + else this.open_branch(this.opened[j], true); + } + if(this.settings.data.async && opn) return; + if(this.cl_count > 0) return; + delete this.opened; + } + if(this.cl_count > 0) return; + + // DOTS and RIGHT TO LEFT + this.container.css("direction","ltr").children("ul:eq(0)").addClass("ltr"); + if(this.settings.ui.dots == false) this.container.children("ul:eq(0)").addClass("no_dots"); + + // REPOSITION SCROLL + if(this.scrtop) { + this.container.scrollTop(_this.scrtop); + delete this.scrtop; + } + // RESELECT PREVIOUSLY SELECTED + if(this.settings.selected !== false) { + $.each(this.settings.selected, function (i) { + if(_this.is_partial_refresh) _this.select_branch($(_this.settings.selected[i].toString().replace('/','\\/'), _this.container), (_this.settings.rules.multiple !== false) ); + else _this.select_branch($(_this.settings.selected[i].toString().replace('/','\\/'), _this.container), (_this.settings.rules.multiple !== false && i > 0) ); + }); + this.settings.selected = false; + } + this.callback("onload", [_this]); + }, + + get : function (obj, format, opts) { + if(!format) format = this.settings.data.type; + if(!opts) opts = this.settings.data.opts; + return new $.tree.datastores[format]().get(obj, this, opts); + }, + + attach_events : function () { + var _this = this; + + this.container + .bind("mousedown.jstree", function (event) { + if(tree_component.drag_drop.isdown) { + tree_component.drag_drop.move_type = false; + event.preventDefault(); + event.stopPropagation(); + event.stopImmediatePropagation(); + return false; + } + }) + .bind("mouseup.jstree", function (event) { + setTimeout( function() { _this.focus.apply(_this); }, 5); + }) + .bind("click.jstree", function (event) { + //event.stopPropagation(); + return true; + }); + $("#" + this.container.attr("id") + " li") + .live("click", function(event) { // WHEN CLICK IS ON THE ARROW + if(event.target.tagName != "LI") return true; + _this.off_height(); + if(event.pageY - $(event.target).offset().top > _this.li_height) return true; + _this.toggle_branch.apply(_this, [event.target]); + event.stopPropagation(); + return false; + }); + $("#" + this.container.attr("id") + " li a") + .live("click.jstree", function (event) { // WHEN CLICK IS ON THE TEXT OR ICON + if(event.which && event.which == 3) return true; + if(_this.locked) { + event.preventDefault(); + event.target.blur(); + return _this.error("LOCKED"); + } + _this.select_branch.apply(_this, [event.target, event.ctrlKey || _this.settings.rules.multiple == "on"]); + if(_this.inp) { _this.inp.blur(); } + event.preventDefault(); + event.target.blur(); + return false; + }) + .live("dblclick.jstree", function (event) { // WHEN DOUBLECLICK ON TEXT OR ICON + if(_this.locked) { + event.preventDefault(); + event.stopPropagation(); + event.target.blur(); + return _this.error("LOCKED"); + } + _this.callback("ondblclk", [_this.get_node(event.target).get(0), _this]); + event.preventDefault(); + event.stopPropagation(); + event.target.blur(); + }) + .live("contextmenu.jstree", function (event) { + if(_this.locked) { + event.target.blur(); + return _this.error("LOCKED"); + } + return _this.callback("onrgtclk", [_this.get_node(event.target).get(0), _this, event]); + }) + .live("mouseover.jstree", function (event) { + if(_this.locked) { + event.preventDefault(); + event.stopPropagation(); + return _this.error("LOCKED"); + } + if(_this.hovered !== false && (event.target.tagName == "A" || event.target.tagName == "INS")) { + _this.hovered.children("a").removeClass("hover"); + _this.hovered = false; + } + _this.callback("onhover",[_this.get_node(event.target).get(0), _this]); + }) + .live("mousedown.jstree", function (event) { + if(_this.settings.rules.drag_button == "left" && event.which && event.which != 1) return true; + if(_this.settings.rules.drag_button == "right" && event.which && event.which != 3) return true; + _this.focus.apply(_this); + if(_this.locked) return _this.error("LOCKED"); + // SELECT LIST ITEM NODE + var obj = _this.get_node(event.target); + // IF ITEM IS DRAGGABLE + if(_this.settings.rules.multiple != false && _this.selected_arr.length > 1 && obj.children("a:eq(0)").hasClass("clicked")) { + var counter = 0; + for(var i in _this.selected_arr) { + if(!_this.selected_arr.hasOwnProperty(i)) continue; + if(_this.check("draggable", _this.selected_arr[i])) { + _this.selected_arr[i].addClass("dragged"); + tree_component.drag_drop.origin_tree = _this; + counter ++; + } + } + if(counter > 0) { + if(_this.check("draggable", obj)) tree_component.drag_drop.drag_node = obj; + else tree_component.drag_drop.drag_node = _this.container.find("li.dragged:eq(0)"); + tree_component.drag_drop.isdown = true; + tree_component.drag_drop.drag_help = $("
            ").append("
              "); + var tmp = tree_component.drag_drop.drag_node.clone(); + if(_this.settings.languages.length > 0) tmp.find("a").not("." + _this.current_lang).hide(); + tree_component.drag_drop.drag_help.children("ul:eq(0)").append(tmp); + tree_component.drag_drop.drag_help.find("li:eq(0)").removeClass("last").addClass("last").children("a").html(" Multiple selection").end().children("ul").remove(); + + tree_component.drag_drop.dragged = _this.container.find("li.dragged"); + } + } + else { + if(_this.check("draggable", obj)) { + tree_component.drag_drop.drag_node = obj; + tree_component.drag_drop.drag_help = $("
              ").append("
                "); + var tmp = obj.clone(); + if(_this.settings.languages.length > 0) tmp.find("a").not("." + _this.current_lang).hide(); + tree_component.drag_drop.drag_help.children("ul:eq(0)").append(tmp); + tree_component.drag_drop.drag_help.find("li:eq(0)").removeClass("last").addClass("last"); + tree_component.drag_drop.isdown = true; + tree_component.drag_drop.foreign = false; + tree_component.drag_drop.origin_tree = _this; + obj.addClass("dragged"); + + tree_component.drag_drop.dragged = _this.container.find("li.dragged"); + } + } + tree_component.drag_drop.init_x = event.pageX; + tree_component.drag_drop.init_y = event.pageY; + obj.blur(); + event.preventDefault(); + event.stopPropagation(); + return false; + }); + }, + focus : function () { + if(this.locked) return false; + if(tree_component.focused != this.cntr) { + tree_component.focused = this.cntr; + this.callback("onfocus",[this]); + } + }, + + off_height : function () { + if(this.offset === false) { + this.container.css({ position : "relative" }); + this.offset = this.container.offset(); + var tmp = 0; + tmp = parseInt($.curCSS(this.container.get(0), "paddingTop", true),10); + if(tmp) this.offset.top += tmp; + tmp = parseInt($.curCSS(this.container.get(0), "borderTopWidth", true),10); + if(tmp) this.offset.top += tmp; + this.container.css({ position : "" }); + } + if(!this.li_height) { + var tmp = this.container.find("ul li.closed, ul li.leaf").eq(0); + this.li_height = tmp.height(); + if(tmp.children("ul:eq(0)").size()) this.li_height -= tmp.children("ul:eq(0)").height(); + if(!this.li_height) this.li_height = 18; + } + }, + scroll_check : function (x,y) { + var _this = this; + var cnt = _this.container; + var off = _this.container.offset(); + + var st = cnt.scrollTop(); + var sl = cnt.scrollLeft(); + // DETECT HORIZONTAL SCROLL + var h_cor = (cnt.get(0).scrollWidth > cnt.width()) ? 40 : 20; + + if(y - off.top < 20) cnt.scrollTop(Math.max( (st - _this.settings.ui.scroll_spd) ,0)); // NEAR TOP + if(cnt.height() - (y - off.top) < h_cor) cnt.scrollTop(st + _this.settings.ui.scroll_spd); // NEAR BOTTOM + if(x - off.left < 20) cnt.scrollLeft(Math.max( (sl - _this.settings.ui.scroll_spd),0)); // NEAR LEFT + if(cnt.width() - (x - off.left) < 40) cnt.scrollLeft(sl + _this.settings.ui.scroll_spd); // NEAR RIGHT + + if(cnt.scrollLeft() != sl || cnt.scrollTop() != st) { + tree_component.drag_drop.move_type = false; + tree_component.drag_drop.ref_node = false; + tree_component.drag_drop.marker.hide(); + } + tree_component.drag_drop.scroll_time = setTimeout( function() { _this.scroll_check(x,y); }, 50); + }, + scroll_into_view : function (obj) { + obj = obj ? this.get_node(obj) : this.selected; + if(!obj) return false; + var off_t = obj.offset().top; + var beg_t = this.container.offset().top; + var end_t = beg_t + this.container.height(); + var h_cor = (this.container.get(0).scrollWidth > this.container.width()) ? 40 : 20; + if(off_t + 5 < beg_t) this.container.scrollTop(this.container.scrollTop() - (beg_t - off_t + 5) ); + if(off_t + h_cor > end_t) this.container.scrollTop(this.container.scrollTop() + (off_t + h_cor - end_t) ); + }, + + get_node : function (obj) { + return $(obj).closest("li"); + }, + get_type : function (obj) { + obj = !obj ? this.selected : this.get_node(obj); + if(!obj) return; + var tmp = obj.attr(this.settings.rules.type_attr); + return tmp || "default"; + }, + set_type : function (str, obj) { + obj = !obj ? this.selected : this.get_node(obj); + if(!obj || !str) return; + obj.attr(this.settings.rules.type_attr, str); + }, + get_text : function (obj, lang) { + obj = this.get_node(obj); + if(!obj || obj.size() == 0) return ""; + if(this.settings.languages && this.settings.languages.length) { + lang = lang ? lang : this.current_lang; + obj = obj.children("a." + lang); + } + else obj = obj.children("a:visible"); + var val = ""; + obj.contents().each(function () { + if(this.nodeType == 3) { val = this.data; return false; } + }); + return val; + }, + + check : function (rule, obj) { + if(this.locked) return false; + var v = false; + // if root node + if(obj === -1) { if(typeof this.settings.rules[rule] != "undefined") v = this.settings.rules[rule]; } + else { + obj = !obj ? this.selected : this.get_node(obj); + if(!obj) return; + var t = this.get_type(obj); + if(typeof this.settings.types[t] != "undefined" && typeof this.settings.types[t][rule] != "undefined") v = this.settings.types[t][rule]; + else if(typeof this.settings.types["default"] != "undefined" && typeof this.settings.types["default"][rule] != "undefined") v = this.settings.types["default"][rule]; + } + if(typeof v == "function") v = v.call(null, obj, this); + v = this.callback("check", [rule, obj, v, this]); + return v; + }, + check_move : function (nod, ref_node, how) { + if(this.locked) return false; + if($(ref_node).closest("li.dragged").size()) return false; + + var tree1 = nod.parents(".tree:eq(0)").get(0); + var tree2 = ref_node.parents(".tree:eq(0)").get(0); + // if different trees + if(tree1 && tree1 != tree2) { + var m = $.tree.reference(tree2.id).settings.rules.multitree; + if(m == "none" || ($.isArray(m) && $.inArray(tree1.id, m) == -1)) return false; + } + + var p = (how != "inside") ? this.parent(ref_node) : this.get_node(ref_node); + nod = this.get_node(nod); + if(p == false) return false; + var r = { + max_depth : this.settings.rules.use_max_depth ? this.check("max_depth", p) : -1, + max_children : this.settings.rules.use_max_children ? this.check("max_children", p) : -1, + valid_children : this.check("valid_children", p) + }; + var nod_type = (typeof nod == "string") ? nod : this.get_type(nod); + if(typeof r.valid_children != "undefined" && (r.valid_children == "none" || (typeof r.valid_children == "object" && $.inArray(nod_type, $.makeArray(r.valid_children)) == -1))) return false; + + if(this.settings.rules.use_max_children) { + if(typeof r.max_children != "undefined" && r.max_children != -1) { + if(r.max_children == 0) return false; + var c_count = 1; + if(tree_component.drag_drop.moving == true && tree_component.drag_drop.foreign == false) { + c_count = tree_component.drag_drop.dragged.size(); + c_count = c_count - p.find('> ul > li.dragged').size(); + } + if(r.max_children < p.find('> ul > li').size() + c_count) return false; + } + } + + if(this.settings.rules.use_max_depth) { + if(typeof r.max_depth != "undefined" && r.max_depth === 0) return this.error("MOVE: MAX-DEPTH REACHED"); + // check for max_depth up the chain + var mx = (r.max_depth > 0) ? r.max_depth : false; + var i = 0; + var t = p; + while(t !== -1) { + t = this.parent(t); + i ++; + var m = this.check("max_depth",t); + if(m >= 0) { + mx = (mx === false) ? (m - i) : Math.min(mx, m - i); + } + if(mx !== false && mx <= 0) return this.error("MOVE: MAX-DEPTH REACHED"); + } + if(mx !== false && mx <= 0) return this.error("MOVE: MAX-DEPTH REACHED"); + if(mx !== false) { + var incr = 1; + if(typeof nod != "string") { + var t = nod; + // possible async problem - when nodes are not all loaded down the chain + while(t.size() > 0) { + if(mx - incr < 0) return this.error("MOVE: MAX-DEPTH REACHED"); + t = t.children("ul").children("li"); + incr ++; + } + } + } + } + if(this.callback("check_move", [nod, ref_node, how, this]) == false) return false; + return true; + }, + + hover_branch : function (obj) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + var obj = _this.get_node(obj); + if(!obj.size()) return this.error("HOVER: NOT A VALID NODE"); + if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE"); + if(this.hovered) this.hovered.children("A").removeClass("hover"); + this.hovered = obj; + this.hovered.children("a").addClass("hover"); + this.scroll_into_view(this.hovered); + }, + select_branch : function (obj, multiple) { + if(this.locked) return this.error("LOCKED"); + if(!obj && this.hovered !== false) obj = this.hovered; + var _this = this; + obj = _this.get_node(obj); + if(!obj.size()) return this.error("SELECT: NOT A VALID NODE"); + obj.children("a").removeClass("hover"); + // CHECK AGAINST RULES FOR SELECTABLE NODES + if(!_this.check("clickable", obj)) return this.error("SELECT: NODE NOT SELECTABLE"); + if(_this.callback("beforechange",[obj.get(0),_this]) === false) return this.error("SELECT: STOPPED BY USER"); + // IF multiple AND obj IS ALREADY SELECTED - DESELECT IT + if(this.settings.rules.multiple != false && multiple && obj.children("a.clicked").size() > 0) { + return this.deselect_branch(obj); + } + if(this.settings.rules.multiple != false && multiple) { + this.selected_arr.push(obj); + } + if(this.settings.rules.multiple != false && !multiple) { + for(var i in this.selected_arr) { + if(!this.selected_arr.hasOwnProperty(i)) continue; + this.selected_arr[i].children("A").removeClass("clicked"); + this.callback("ondeselect", [this.selected_arr[i].get(0), _this]); + } + this.selected_arr = []; + this.selected_arr.push(obj); + if(this.selected && this.selected.children("A").hasClass("clicked")) { + this.selected.children("A").removeClass("clicked"); + this.callback("ondeselect", [this.selected.get(0), _this]); + } + } + if(!this.settings.rules.multiple) { + if(this.selected) { + this.selected.children("A").removeClass("clicked"); + this.callback("ondeselect", [this.selected.get(0), _this]); + } + } + // SAVE NEWLY SELECTED + this.selected = obj; + if(this.hovered !== false) { + this.hovered.children("A").removeClass("hover"); + this.hovered = obj; + } + + // FOCUS NEW NODE AND OPEN ALL PARENT NODES IF CLOSED + this.selected.children("a").addClass("clicked").end().parents("li.closed").each( function () { _this.open_branch(this, true); }); + + // SCROLL SELECTED NODE INTO VIEW + this.scroll_into_view(this.selected); + + this.callback("onselect", [this.selected.get(0), _this]); + this.callback("onchange", [this.selected.get(0), _this]); + }, + deselect_branch : function (obj) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + var obj = this.get_node(obj); + if(obj.children("a.clicked").size() == 0) return this.error("DESELECT: NODE NOT SELECTED"); + + obj.children("a").removeClass("clicked"); + this.callback("ondeselect", [obj.get(0), _this]); + if(this.settings.rules.multiple != false && this.selected_arr.length > 1) { + this.selected_arr = []; + this.container.find("a.clicked").filter(":first-child").parent().each(function () { + _this.selected_arr.push($(this)); + }); + if(obj.get(0) == this.selected.get(0)) { + this.selected = this.selected_arr[0]; + } + } + else { + if(this.settings.rules.multiple != false) this.selected_arr = []; + this.selected = false; + } + this.callback("onchange", [obj.get(0), _this]); + }, + toggle_branch : function (obj) { + if(this.locked) return this.error("LOCKED"); + var obj = this.get_node(obj); + if(obj.hasClass("closed")) return this.open_branch(obj); + if(obj.hasClass("open")) return this.close_branch(obj); + }, + open_branch : function (obj, disable_animation, callback) { + var _this = this; + + if(this.locked) return this.error("LOCKED"); + var obj = this.get_node(obj); + if(!obj.size()) return this.error("OPEN: NO SUCH NODE"); + if(obj.hasClass("leaf")) return this.error("OPEN: OPENING LEAF NODE"); + if(this.settings.data.async && obj.find("li").size() == 0) { + + if(this.callback("beforeopen",[obj.get(0),this]) === false) return this.error("OPEN: STOPPED BY USER"); + + obj.children("ul:eq(0)").remove().end().append(""); + obj.removeClass("closed").addClass("open"); + + var _datastore = new $.tree.datastores[this.settings.data.type](); + _datastore.load(this.callback("beforedata",[obj,this]),this,this.settings.data.opts,function(data){ + data = _this.callback("ondata", [data, _this]); + if(!data || data.length == 0) { + obj.removeClass("closed").removeClass("open").addClass("leaf").children("ul").remove(); + if(callback) callback.call(); + return; + } + _datastore.parse(data,_this,_this.settings.data.opts,function(str){ + str = _this.callback("onparse", [str, _this]); + // if(obj.children('ul:eq(0)').children('li').size() > 1) obj.children("ul").find('.loaading').parent().replaceWith(str); else + obj.children("ul:eq(0)").replaceWith($("
                  ").html(str)); + obj.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed"); + obj.find("li").not(".open").not(".closed").addClass("leaf"); + _this.open_branch.apply(_this, [obj]); + if(callback) callback.call(); + }); + }); + return true; + } + else { + if(!this.settings.data.async) { + if(this.callback("beforeopen",[obj.get(0),this]) === false) return this.error("OPEN: STOPPED BY USER"); + } + if(parseInt(this.settings.ui.animation) > 0 && !disable_animation ) { + obj.children("ul:eq(0)").css("display","none"); + obj.removeClass("closed").addClass("open"); + obj.children("ul:eq(0)").slideDown(parseInt(this.settings.ui.animation), function() { + $(this).css("display",""); + if(callback) callback.call(); + }); + } else { + obj.removeClass("closed").addClass("open"); + if(callback) callback.call(); + } + this.callback("onopen", [obj.get(0), this]); + return true; + } + }, + close_branch : function (obj, disable_animation) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + var obj = this.get_node(obj); + if(!obj.size()) return this.error("CLOSE: NO SUCH NODE"); + if(_this.callback("beforeclose",[obj.get(0),_this]) === false) return this.error("CLOSE: STOPPED BY USER"); + if(parseInt(this.settings.ui.animation) > 0 && !disable_animation && obj.children("ul:eq(0)").size() == 1) { + obj.children("ul:eq(0)").slideUp(parseInt(this.settings.ui.animation), function() { + if(obj.hasClass("open")) obj.removeClass("open").addClass("closed"); + $(this).css("display",""); + }); + } + else { + if(obj.hasClass("open")) obj.removeClass("open").addClass("closed"); + } + if(this.selected && this.settings.ui.selected_parent_close !== false && obj.children("ul:eq(0)").find("a.clicked").size() > 0) { + obj.find("li:has(a.clicked)").each(function() { + _this.deselect_branch(this); + }); + if(this.settings.ui.selected_parent_close == "select_parent" && obj.children("a.clicked").size() == 0) this.select_branch(obj, (this.settings.rules.multiple != false && this.selected_arr.length > 0) ); + } + this.callback("onclose", [obj.get(0), this]); + }, + open_all : function (obj, callback) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + obj = obj ? this.get_node(obj) : this.container; + + var s = obj.find("li.closed").size(); + if(!callback) this.cl_count = 0; + else this.cl_count --; + if(s > 0) { + this.cl_count += s; + // maybe add .andSelf() + obj.find("li.closed").each( function () { var __this = this; _this.open_branch.apply(_this, [this, true, function() { _this.open_all.apply(_this, [__this, true]); } ]); }); + } + else if(this.cl_count == 0) this.callback("onopen_all",[this]); + }, + close_all : function (obj) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + obj = obj ? this.get_node(obj) : this.container; + // maybe add .andSelf() + obj.find("li.open").each( function () { _this.close_branch(this, true); }); + this.callback("onclose_all",[this]); + }, + + set_lang : function (i) { + if(!$.isArray(this.settings.languages) || this.settings.languages.length == 0) return false; + if(this.locked) return this.error("LOCKED"); + if(!$.inArray(i,this.settings.languages) && typeof this.settings.languages[i] != "undefined") i = this.settings.languages[i]; + if(typeof i == "undefined") return false; + if(i == this.current_lang) return true; + var st = false; + var id = "#" + this.container.attr("id"); + st = tree_component.get_css(id + " ." + this.current_lang); + if(st !== false) st.style.display = "none"; + st = tree_component.get_css(id + " ." + i); + if(st !== false) st.style.display = ""; + this.current_lang = i; + return true; + }, + get_lang : function () { + if(!$.isArray(this.settings.languages) || this.settings.languages.length == 0) return false; + return this.current_lang; + }, + + create : function (obj, ref_node, position) { + if(this.locked) return this.error("LOCKED"); + + var root = false; + if(ref_node == -1) { root = true; ref_node = this.container; } + else ref_node = ref_node ? this.get_node(ref_node) : this.selected; + + if(!root && (!ref_node || !ref_node.size())) return this.error("CREATE: NO NODE SELECTED"); + + var pos = position; + + var tmp = ref_node; // for type calculation + if(position == "before") { + position = ref_node.parent().children().index(ref_node); + ref_node = ref_node.parents("li:eq(0)"); + } + if(position == "after") { + position = ref_node.parent().children().index(ref_node) + 1; + ref_node = ref_node.parents("li:eq(0)"); + } + if(!root && ref_node.size() == 0) { root = true; ref_node = this.container; } + + if(!root) { + if(!this.check("creatable", ref_node)) return this.error("CREATE: CANNOT CREATE IN NODE"); + if(ref_node.hasClass("closed")) { + if(this.settings.data.async && ref_node.children("ul").size() == 0) { + var _this = this; + return this.open_branch(ref_node, true, function () { _this.create.apply(_this, [obj, ref_node, position]); } ); + } + else this.open_branch(ref_node, true); + } + } + + // creating new object to pass to parseJSON + var torename = false; + if(!obj) obj = {}; + else obj = $.extend(true, {}, obj); + if(!obj.attributes) obj.attributes = {}; + if(!obj.attributes[this.settings.rules.type_attr]) obj.attributes[this.settings.rules.type_attr] = this.get_type(tmp) || "default"; + if(this.settings.languages.length) { + if(!obj.data) { obj.data = {}; torename = true; } + for(var i = 0; i < this.settings.languages.length; i++) { + if(!obj.data[this.settings.languages[i]]) obj.data[this.settings.languages[i]] = ((typeof this.settings.lang.new_node).toLowerCase() != "string" && this.settings.lang.new_node[i]) ? this.settings.lang.new_node[i] : this.settings.lang.new_node; + } + } + else { + if(!obj.data) { obj.data = this.settings.lang.new_node; torename = true; } + } + + obj = this.callback("ondata",[obj, this]); + var obj_s = $.tree.datastores.json().parse(obj,this); + obj_s = this.callback("onparse", [obj_s, this]); + var $li = $(obj_s); + + if($li.children("ul").size()) { + if(!$li.is(".open")) $li.addClass("closed"); + } + else $li.addClass("leaf"); + $li.find("li:last-child").addClass("last").end().find("li:has(ul)").not(".open").addClass("closed"); + $li.find("li").not(".open").not(".closed").addClass("leaf"); + + var r = { + max_depth : this.settings.rules.use_max_depth ? this.check("max_depth", (root ? -1 : ref_node) ) : -1, + max_children : this.settings.rules.use_max_children ? this.check("max_children", (root ? -1 : ref_node) ) : -1, + valid_children : this.check("valid_children", (root ? -1 : ref_node) ) + }; + var nod_type = this.get_type($li); + if(typeof r.valid_children != "undefined" && (r.valid_children == "none" || ($.isArray(r.valid_children) && $.inArray(nod_type, r.valid_children) == -1))) return this.error("CREATE: NODE NOT A VALID CHILD"); + + if(this.settings.rules.use_max_children) { + if(typeof r.max_children != "undefined" && r.max_children != -1 && r.max_children >= this.children(ref_node).size()) return this.error("CREATE: MAX_CHILDREN REACHED"); + } + + if(this.settings.rules.use_max_depth) { + if(typeof r.max_depth != "undefined" && r.max_depth === 0) return this.error("CREATE: MAX-DEPTH REACHED"); + // check for max_depth up the chain + var mx = (r.max_depth > 0) ? r.max_depth : false; + var i = 0; + var t = ref_node; + + while(t !== -1 && !root) { + t = this.parent(t); + i ++; + var m = this.check("max_depth",t); + if(m >= 0) { + mx = (mx === false) ? (m - i) : Math.min(mx, m - i); + } + if(mx !== false && mx <= 0) return this.error("CREATE: MAX-DEPTH REACHED"); + } + if(mx !== false && mx <= 0) return this.error("CREATE: MAX-DEPTH REACHED"); + if(mx !== false) { + var incr = 1; + var t = $li; + while(t.size() > 0) { + if(mx - incr < 0) return this.error("CREATE: MAX-DEPTH REACHED"); + t = t.children("ul").children("li"); + incr ++; + } + } + } + + if((typeof position).toLowerCase() == "undefined" || position == "inside") + position = (this.settings.rules.createat == "top") ? 0 : ref_node.children("ul:eq(0)").children("li").size(); + if(ref_node.children("ul").size() == 0 || (root == true && ref_node.children("ul").children("li").size() == 0) ) { + if(!root) var a = this.moved($li,ref_node.children("a:eq(0)"),"inside", true); + else var a = this.moved($li,this.container.children("ul:eq(0)"),"inside", true); + } + else if(pos == "before" && ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", true); + else if(pos == "after" && ref_node.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size()) + var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after", true); + else if(ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", true); + else + var a = this.moved($li,ref_node.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after",true); + + if(a === false) return this.error("CREATE: ABORTED"); + + if(torename) { + this.select_branch($li.children("a:eq(0)")); + this.rename(); + } + return $li; + }, + rename : function (obj, new_name) { + if(this.locked) return this.error("LOCKED"); + obj = obj ? this.get_node(obj) : this.selected; + var _this = this; + if(!obj || !obj.size()) return this.error("RENAME: NO NODE SELECTED"); + if(!this.check("renameable", obj)) return this.error("RENAME: NODE NOT RENAMABLE"); + if(!this.callback("beforerename",[obj.get(0), _this.current_lang, _this])) return this.error("RENAME: STOPPED BY USER"); + + obj.parents("li.closed").each(function () { _this.open_branch(this) }); + if(this.current_lang) obj = obj.find("a." + this.current_lang); + else obj = obj.find("a:first"); + + // Rollback + var rb = {}; + rb[this.container.attr("id")] = this.get_rollback(); + + var icn = obj.children("ins").clone(); + if((typeof new_name).toLowerCase() == "string") { + obj.text(new_name).prepend(icn); + _this.callback("onrename", [_this.get_node(obj).get(0), _this, rb]); + } + else { + var last_value = ""; + obj.contents().each(function () { + if(this.nodeType == 3) { last_value = this.data; return false; } + }); + _this.inp = $(""); + _this.inp + .val(last_value.replace(/&/g,"&").replace(/>/g,">").replace(/</g,"<")) + .bind("mousedown", function (event) { event.stopPropagation(); }) + .bind("mouseup", function (event) { event.stopPropagation(); }) + .bind("click", function (event) { event.stopPropagation(); }) + .bind("keyup", function (event) { + var key = event.keyCode || event.which; + if(key == 27) { this.value = last_value; this.blur(); return } + if(key == 13) { this.blur(); return; } + }); + _this.inp.blur(function(event) { + if(this.value == "") this.value = last_value; + obj.text(this.value).prepend(icn); + obj.get(0).style.display = ""; + obj.prevAll("span").remove(); + _this.inp = false; + _this.callback("onrename", [_this.get_node(obj).get(0), _this, rb]); + }); + + var spn = $("").addClass(obj.attr("class")).append(icn).append(_this.inp); + obj.get(0).style.display = "none"; + obj.parent().prepend(spn); + _this.inp.get(0).focus(); + _this.inp.get(0).select(); + } + }, + remove : function(obj) { + if(this.locked) return this.error("LOCKED"); + var _this = this; + + // Rollback + var rb = {}; + rb[this.container.attr("id")] = this.get_rollback(); + + if(obj && (!this.selected || this.get_node(obj).get(0) != this.selected.get(0) )) { + obj = this.get_node(obj); + if(obj.size()) { + if(!this.check("deletable", obj)) return this.error("DELETE: NODE NOT DELETABLE"); + if(!this.callback("beforedelete",[obj.get(0), _this])) return this.error("DELETE: STOPPED BY USER"); + $parent = obj.parent(); + if(obj.find("a.clicked").size()) { + var reset_selected = false; + _this.selected_arr = []; + this.container.find("a.clicked").filter(":first-child").parent().each(function () { + if(!reset_selected && this == _this.selected.get(0)) reset_selected = true; + if($(this).parents().index(obj) != -1) return true; + _this.selected_arr.push($(this)); + }); + if(reset_selected) this.selected = this.selected_arr[0] || false; + } + obj = obj.remove(); + $parent.children("li:last").addClass("last"); + if($parent.children("li").size() == 0) { + $li = $parent.parents("li:eq(0)"); + $li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove(); + } + this.callback("ondelete", [obj.get(0), this, rb]); + } + } + else if(this.selected) { + if(!this.check("deletable", this.selected)) return this.error("DELETE: NODE NOT DELETABLE"); + if(!this.callback("beforedelete",[this.selected.get(0), _this])) return this.error("DELETE: STOPPED BY USER"); + $parent = this.selected.parent(); + var obj = this.selected; + if(this.settings.rules.multiple == false || this.selected_arr.length == 1) { + var stop = true; + var tmp = this.settings.ui.selected_delete == "select_previous" ? this.prev(this.selected) : false; + } + obj = obj.remove(); + $parent.children("li:last").addClass("last"); + if($parent.children("li").size() == 0) { + $li = $parent.parents("li:eq(0)"); + $li.removeClass("open").removeClass("closed").addClass("leaf").children("ul").remove(); + } + if(!stop && this.settings.rules.multiple != false) { + var _this = this; + this.selected_arr = []; + this.container.find("a.clicked").filter(":first-child").parent().each(function () { + _this.selected_arr.push($(this)); + }); + if(this.selected_arr.length > 0) { + this.selected = this.selected_arr[0]; + this.remove(); + } + } + if(stop && tmp) this.select_branch(tmp); + this.callback("ondelete", [obj.get(0), this, rb]); + } + else return this.error("DELETE: NO NODE SELECTED"); + }, + + next : function (obj, strict) { + obj = this.get_node(obj); + if(!obj.size()) return false; + if(strict) return (obj.nextAll("li").size() > 0) ? obj.nextAll("li:eq(0)") : false; + + if(obj.hasClass("open")) return obj.find("li:eq(0)"); + else if(obj.nextAll("li").size() > 0) return obj.nextAll("li:eq(0)"); + else return obj.parents("li").next("li").eq(0); + }, + prev : function(obj, strict) { + obj = this.get_node(obj); + if(!obj.size()) return false; + if(strict) return (obj.prevAll("li").size() > 0) ? obj.prevAll("li:eq(0)") : false; + + if(obj.prev("li").size()) { + var obj = obj.prev("li").eq(0); + while(obj.hasClass("open")) obj = obj.children("ul:eq(0)").children("li:last"); + return obj; + } + else return obj.parents("li:eq(0)").size() ? obj.parents("li:eq(0)") : false; + }, + parent : function(obj) { + obj = this.get_node(obj); + if(!obj.size()) return false; + return obj.parents("li:eq(0)").size() ? obj.parents("li:eq(0)") : -1; + }, + children : function(obj) { + if(obj === -1) return this.container.children("ul:eq(0)").children("li"); + + obj = this.get_node(obj); + if(!obj.size()) return false; + return obj.children("ul:eq(0)").children("li"); + }, + + toggle_dots : function () { + if(this.settings.ui.dots) { + this.settings.ui.dots = false; + this.container.children("ul:eq(0)").addClass("no_dots"); + } + else { + this.settings.ui.dots = true; + this.container.children("ul:eq(0)").removeClass("no_dots"); + } + }, + + callback : function (cb, args) { + var p = false; + var r = null; + for(var i in this.settings.plugins) { + if(typeof $.tree.plugins[i] != "object") continue; + p = $.tree.plugins[i]; + if(p.callbacks && typeof p.callbacks[cb] == "function") r = p.callbacks[cb].apply(this, args); + if(typeof r !== "undefined" && r !== null) { + if(cb == "ondata" || cb == "onparse") args[0] = r; // keep the chain if data or parse + else return r; + } + } + p = this.settings.callback[cb]; + if(typeof p == "function") return p.apply(null, args); + }, + get_rollback : function () { + var rb = {}; + rb.html = this.container.html(); + rb.selected = this.selected ? this.selected.attr("id") : false; + return rb; + }, + moved : function (what, where, how, is_new, is_copy, rb) { + var what = $(what); + var $parent = $(what).parents("ul:eq(0)"); + var $where = $(where); + if($where.is("ins")) $where = $where.parent(); + + // Rollback + if(!rb) { + var rb = {}; + rb[this.container.attr("id")] = this.get_rollback(); + if(!is_new) { + var tmp = what.size() > 1 ? what.eq(0).parents(".tree:eq(0)") : what.parents(".tree:eq(0)"); + if(tmp.get(0) != this.container.get(0)) { + tmp = tree_component.inst[tmp.attr("id")]; + rb[tmp.container.attr("id")] = tmp.get_rollback(); + } + delete tmp; + } + } + + if(how == "inside" && this.settings.data.async) { + var _this = this; + if(this.get_node($where).hasClass("closed")) { + return this.open_branch(this.get_node($where), true, function () { _this.moved.apply(_this, [what, where, how, is_new, is_copy, rb]); }); + } + if(this.get_node($where).find("> ul > li > a.loading").size() == 1) { + setTimeout(function () { _this.moved.apply(_this, [what, where, how, is_new, is_copy]); }, 200); + return; + } + } + + + // IF MULTIPLE + if(what.size() > 1) { + var _this = this; + var tmp = this.moved(what.eq(0), where, how, false, is_copy, rb); + what.each(function (i) { + if(i == 0) return; + if(tmp) { // if tmp is false - the previous move was a no-go + tmp = _this.moved(this, tmp.children("a:eq(0)"), "after", false, is_copy, rb); + } + }); + return what; + } + + if(is_copy) { + _what = what.clone(); + _what.each(function (i) { + this.id = this.id + "_copy"; + $(this).find("li").each(function () { + this.id = this.id + "_copy"; + }); + $(this).removeClass("dragged").find("a.clicked").removeClass("clicked").end().find("li.dragged").removeClass("dragged"); + }); + } + else _what = what; + if(is_new) { + if(!this.callback("beforecreate", [this.get_node(what).get(0), this.get_node(where).get(0),how,this])) return false; + } + else { + if(!this.callback("beforemove", [this.get_node(what).get(0), this.get_node(where).get(0),how,this])) return false; + } + + if(!is_new) { + var tmp = what.parents(".tree:eq(0)"); + // if different trees + if(tmp.get(0) != this.container.get(0)) { + tmp = tree_component.inst[tmp.attr("id")]; + + // if there are languages - otherwise - no cleanup needed + if(tmp.settings.languages.length) { + var res = []; + // if new tree has no languages - use current visible + if(this.settings.languages.length == 0) res.push("." + tmp.current_lang); + else { + for(var i in this.settings.languages) { + if(!this.settings.languages.hasOwnProperty(i)) continue; + for(var j in tmp.settings.languages) { + if(!tmp.settings.languages.hasOwnProperty(j)) continue; + if(this.settings.languages[i] == tmp.settings.languages[j]) res.push("." + this.settings.languages[i]); + } + } + } + if(res.length == 0) return this.error("MOVE: NO COMMON LANGUAGES"); + _what.find("a").not(res.join(",")).remove(); + } + _what.find("a.clicked").removeClass("clicked"); + } + } + what = _what; + + // ADD NODE TO NEW PLACE + switch(how) { + case "before": + $where.parents("ul:eq(0)").children("li.last").removeClass("last"); + $where.parent().before(what.removeClass("last")); + $where.parents("ul:eq(0)").children("li:last").addClass("last"); + break; + case "after": + $where.parents("ul:eq(0)").children("li.last").removeClass("last"); + $where.parent().after(what.removeClass("last")); + $where.parents("ul:eq(0)").children("li:last").addClass("last"); + break; + case "inside": + if($where.parent().children("ul:first").size()) { + if(this.settings.rules.createat == "top") { + $where.parent().children("ul:first").prepend(what.removeClass("last")).children("li:last").addClass("last"); + + // restored this section + var tmp_node = $where.parent().children("ul:first").children("li:first"); + if(tmp_node.size()) { + how = "before"; + where = tmp_node; + } + } + else { + // restored this section + var tmp_node = $where.parent().children("ul:first").children(".last"); + if(tmp_node.size()) { + how = "after"; + where = tmp_node; + } + + $where.parent().children("ul:first").children(".last").removeClass("last").end().append(what.removeClass("last")).children("li:last").addClass("last"); + } + } + else { + what.addClass("last"); + $where.parent().removeClass("leaf").append("
                    "); + if(!$where.parent().hasClass("open")) $where.parent().addClass("closed"); + $where.parent().children("ul:first").prepend(what); + } + if($where.parent().hasClass("closed")) { this.open_branch($where); } + break; + default: + break; + } + // CLEANUP OLD PARENT + if($parent.find("li").size() == 0) { + var $li = $parent.parent(); + $li.removeClass("open").removeClass("closed").addClass("leaf"); + if(!$li.is(".tree")) $li.children("ul").remove(); + $li.parents("ul:eq(0)").children("li.last").removeClass("last").end().children("li:last").addClass("last"); + } + else { + $parent.children("li.last").removeClass("last"); + $parent.children("li:last").addClass("last"); + } + + // NO LONGER CORRECT WITH position PARAM - if(is_new && how != "inside") where = this.get_node(where).parents("li:eq(0)"); + if(is_copy) this.callback("oncopy", [this.get_node(what).get(0), this.get_node(where).get(0), how, this, rb]); + else if(is_new) this.callback("oncreate", [this.get_node(what).get(0), ($where.is("ul") ? -1 : this.get_node(where).get(0) ), how, this, rb]); + else this.callback("onmove", [this.get_node(what).get(0), this.get_node(where).get(0), how, this, rb]); + return what; + }, + error : function (code) { + this.callback("error",[code,this]); + return false; + }, + lock : function (state) { + this.locked = state; + if(this.locked) this.container.children("ul:eq(0)").addClass("locked"); + else this.container.children("ul:eq(0)").removeClass("locked"); + }, + cut : function (obj) { + if(this.locked) return this.error("LOCKED"); + obj = obj ? this.get_node(obj) : this.container.find("a.clicked").filter(":first-child").parent(); + if(!obj || !obj.size()) return this.error("CUT: NO NODE SELECTED"); + tree_component.cut_copy.copy_nodes = false; + tree_component.cut_copy.cut_nodes = obj; + }, + copy : function (obj) { + if(this.locked) return this.error("LOCKED"); + obj = obj ? this.get_node(obj) : this.container.find("a.clicked").filter(":first-child").parent(); + if(!obj || !obj.size()) return this.error("COPY: NO NODE SELECTED"); + tree_component.cut_copy.copy_nodes = obj; + tree_component.cut_copy.cut_nodes = false; + }, + paste : function (obj, position) { + if(this.locked) return this.error("LOCKED"); + + var root = false; + if(obj == -1) { root = true; obj = this.container; } + else obj = obj ? this.get_node(obj) : this.selected; + + if(!root && (!obj || !obj.size())) return this.error("PASTE: NO NODE SELECTED"); + if(!tree_component.cut_copy.copy_nodes && !tree_component.cut_copy.cut_nodes) return this.error("PASTE: NOTHING TO DO"); + + var _this = this; + + var pos = position; + + if(position == "before") { + position = obj.parent().children().index(obj); + obj = obj.parents("li:eq(0)"); + } + else if(position == "after") { + position = obj.parent().children().index(obj) + 1; + obj = obj.parents("li:eq(0)"); + } + else if((typeof position).toLowerCase() == "undefined" || position == "inside") { + position = (this.settings.rules.createat == "top") ? 0 : obj.children("ul:eq(0)").children("li").size(); + } + if(!root && obj.size() == 0) { root = true; obj = this.container; } + + if(tree_component.cut_copy.copy_nodes && tree_component.cut_copy.copy_nodes.size()) { + var ok = true; + if(!root && !this.check_move(tree_component.cut_copy.copy_nodes, obj.children("a:eq(0)"), "inside")) return false; + + if(obj.children("ul").size() == 0 || (root == true && obj.children("ul").children("li").size() == 0) ) { + if(!root) var a = this.moved(tree_component.cut_copy.copy_nodes,obj.children("a:eq(0)"),"inside", false, true); + else var a = this.moved(tree_component.cut_copy.copy_nodes,this.container.children("ul:eq(0)"),"inside", false, true); + } + else if(pos == "before" && obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", false, true); + else if(pos == "after" && obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size()) + var a = this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after", false, true); + else if(obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before", false, true); + else + var a = this.moved(tree_component.cut_copy.copy_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after", false, true); + tree_component.cut_copy.copy_nodes = false; + } + if(tree_component.cut_copy.cut_nodes && tree_component.cut_copy.cut_nodes.size()) { + var ok = true; + obj.parents().andSelf().each(function () { + if(tree_component.cut_copy.cut_nodes.index(this) != -1) { + ok = false; + return false; + } + }); + if(!ok) return this.error("Invalid paste"); + if(!root && !this.check_move(tree_component.cut_copy.cut_nodes, obj.children("a:eq(0)"), "inside")) return false; + + if(obj.children("ul").size() == 0 || (root == true && obj.children("ul").children("li").size() == 0) ) { + if(!root) var a = this.moved(tree_component.cut_copy.cut_nodes,obj.children("a:eq(0)"),"inside"); + else var a = this.moved(tree_component.cut_copy.cut_nodes,this.container.children("ul:eq(0)"),"inside"); + } + else if(pos == "before" && obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before"); + else if(pos == "after" && obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").size()) + var a = this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position) + ")").children("a:eq(0)"),"after"); + else if(obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").size()) + var a = this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:nth-child(" + (position + 1) + ")").children("a:eq(0)"),"before"); + else + var a = this.moved(tree_component.cut_copy.cut_nodes,obj.children("ul:eq(0)").children("li:last").children("a:eq(0)"),"after"); + tree_component.cut_copy.cut_nodes = false; + } + }, + search : function(str, func) { + var _this = this; + if(!str || (this.srch && str != this.srch) ) { + this.srch = ""; + this.srch_opn = false; + this.container.find("a.search").removeClass("search"); + } + this.srch = str; + if(!str) return; + + if(!func) func = "contains"; + if(this.settings.data.async) { + if(!this.srch_opn) { + var dd = $.extend( { "search" : str } , this.callback("beforedata", [false, this] ) ); + $.ajax({ + type : this.settings.data.opts.method, + url : this.settings.data.opts.url, + data : dd, + dataType : "text", + success : function (data) { + _this.srch_opn = $.unique(data.split(",")); + _this.search.apply(_this,[str, func]); + } + }); + } + else if(this.srch_opn.length) { + if(this.srch_opn && this.srch_opn.length) { + var opn = false; + for(var j = 0; j < this.srch_opn.length; j++) { + if(this.get_node("#" + this.srch_opn[j]).size() > 0) { + opn = true; + var tmp = "#" + this.srch_opn[j]; + delete this.srch_opn[j]; + this.open_branch(tmp, true, function () { _this.search.apply(_this,[str, func]); } ); + } + } + if(!opn) { + this.srch_opn = []; + _this.search.apply(_this,[str, func]); + } + } + } + else { + this.srch_opn = false; + var selector = "a"; + // IF LANGUAGE VERSIONS + if(this.settings.languages.length) selector += "." + this.current_lang; + this.callback("onsearch", [this.container.find(selector + ":" + func + "('" + str + "')"), this]); + } + } + else { + var selector = "a"; + // IF LANGUAGE VERSIONS + if(this.settings.languages.length) selector += "." + this.current_lang; + var nn = this.container.find(selector + ":" + func + "('" + str + "')"); + nn.parents("li.closed").each( function () { _this.open_branch(this, true); }); + this.callback("onsearch", [nn, this]); + } + }, + add_sheet : tree_component.add_sheet, + + destroy : function() { + this.callback("ondestroy", [this]); + + this.container.unbind(".jstree"); + $("#" + this.container.attr("id")).die("click.jstree").die("dblclick.jstree").die("mouseover.jstree").die("mouseout.jstree").die("mousedown.jstree"); + this.container.removeClass("tree ui-widget ui-widget-content tree-default tree-" + this.settings.ui.theme_name).children("ul").removeClass("no_dots ltr locked").find("li").removeClass("leaf").removeClass("open").removeClass("closed").removeClass("last").children("a").removeClass("clicked hover search"); + + if(this.cntr == tree_component.focused) { + for(var i in tree_component.inst) { + if(i != this.cntr && i != this.container.attr("id")) { + tree_component.inst[i].focus(); + break; + } + } + } + + tree_component.inst[this.cntr] = false; + tree_component.inst[this.container.attr("id")] = false; + delete tree_component.inst[this.cntr]; + delete tree_component.inst[this.container.attr("id")]; + tree_component.cntr --; + } + } + }; + + // instance manager + tree_component.cntr = 0; + tree_component.inst = {}; + + // themes + tree_component.themes = []; + + // drag'n'drop stuff + tree_component.drag_drop = { + isdown : false, // Is there a drag + drag_node : false, // The actual node + drag_help : false, // The helper + dragged : false, + + init_x : false, + init_y : false, + moving : false, + + origin_tree : false, + marker : false, + + move_type : false, // before, after or inside + ref_node : false, // reference node + appended : false, // is helper appended + + foreign : false, // Is the dragged node a foreign one + droppable : [], // Array of classes that can be dropped onto the tree + + open_time : false, // Timeout for opening nodes + scroll_time : false // Timeout for scrolling + }; + tree_component.mouseup = function(event) { + var tmp = tree_component.drag_drop; + if(tmp.open_time) clearTimeout(tmp.open_time); + if(tmp.scroll_time) clearTimeout(tmp.scroll_time); + + if(tmp.moving && $.tree.drag_end !== false) $.tree.drag_end.call(null, event, tmp); + + if(tmp.foreign === false && tmp.drag_node && tmp.drag_node.size()) { + tmp.drag_help.remove(); + if(tmp.move_type) { + var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")]; + if(tree1) tree1.moved(tmp.dragged, tmp.ref_node, tmp.move_type, false, (tmp.origin_tree.settings.rules.drag_copy == "on" || (tmp.origin_tree.settings.rules.drag_copy == "ctrl" && event.ctrlKey) ) ); + } + tmp.move_type = false; + tmp.ref_node = false; + } + if(tmp.foreign !== false) { + if(tmp.drag_help) tmp.drag_help.remove(); + if(tmp.move_type) { + var tree1 = tree_component.inst[tmp.ref_node.parents(".tree:eq(0)").attr("id")]; + if(tree1) tree1.callback("ondrop",[tmp.f_data, tree1.get_node(tmp.ref_node).get(0), tmp.move_type, tree1]); + } + tmp.foreign = false; + tmp.move_type = false; + tmp.ref_node = false; + } + // RESET EVERYTHING + if(tree_component.drag_drop.marker) tree_component.drag_drop.marker.hide(); + if(tmp.dragged && tmp.dragged.size()) tmp.dragged.removeClass("dragged"); + tmp.dragged = false; + tmp.drag_help = false; + tmp.drag_node = false; + tmp.f_type = false; + tmp.f_data = false; + tmp.init_x = false; + tmp.init_y = false; + tmp.moving = false; + tmp.appended = false; + tmp.origin_tree = false; + if(tmp.isdown) { + tmp.isdown = false; + event.preventDefault(); + event.stopPropagation(); + return false; + } + }; + tree_component.mousemove = function(event) { + var tmp = tree_component.drag_drop; + var is_start = false; + + if(tmp.isdown) { + if(!tmp.moving && Math.abs(tmp.init_x - event.pageX) < 5 && Math.abs(tmp.init_y - event.pageY) < 5) { + event.preventDefault(); + event.stopPropagation(); + return false; + } + else { + if(!tmp.moving) { + tree_component.drag_drop.moving = true; + is_start = true; + } + } + + if(tmp.open_time) clearTimeout(tmp.open_time); + + if(tmp.drag_help !== false) { + if(!tmp.appended) { + if(tmp.foreign !== false) tmp.origin_tree = $.tree.focused(); + $("body").append(tmp.drag_help); + tmp.w = tmp.drag_help.width(); + tmp.appended = true; + } + tmp.drag_help.css({ "left" : (event.pageX + 5 ), "top" : (event.pageY + 15) }); + } + + if(is_start && $.tree.drag_start !== false) $.tree.drag_start.call(null, event, tmp); + if($.tree.drag !== false) $.tree.drag.call(null, event, tmp); + + if(event.target.tagName == "DIV" && event.target.id == "jstree-marker") return false; + + var et = $(event.target); + if(et.is("ins")) et = et.parent(); + var cnt = et.is(".tree") ? et : et.parents(".tree:eq(0)"); + + // if not moving over a tree + if(cnt.size() == 0 || !tree_component.inst[cnt.attr("id")]) { + if(tmp.scroll_time) clearTimeout(tmp.scroll_time); + if(tmp.drag_help !== false) tmp.drag_help.find("li:eq(0) ins").addClass("forbidden"); + tmp.move_type = false; + tmp.ref_node = false; + tree_component.drag_drop.marker.hide(); + return false; + } + + var tree2 = tree_component.inst[cnt.attr("id")]; + tree2.off_height(); + + if(tmp.scroll_time) clearTimeout(tmp.scroll_time); + tmp.scroll_time = setTimeout( function() { tree2.scroll_check(event.pageX,event.pageY); }, 50); + + var mov = false; + var st = cnt.scrollTop(); + + if(event.target.tagName == "A" || event.target.tagName == "INS") { + // just in case if hover is over the draggable + if(et.is("#jstree-dragged")) return false; + if(tree2.get_node(event.target).hasClass("closed")) { + tmp.open_time = setTimeout( function () { tree2.open_branch(et); }, 500); + } + + var et_off = et.offset(); + var goTo = { + x : (et_off.left - 1), + y : (event.pageY - et_off.top) + }; + + var arr = []; + if(goTo.y < tree2.li_height/3 + 1 ) arr = ["before","inside","after"]; + else if(goTo.y > tree2.li_height*2/3 - 1 ) arr = ["after","inside","before"]; + else { + if(goTo.y < tree2.li_height/2) arr = ["inside","before","after"]; + else arr = ["inside","after","before"]; + } + var ok = false; + var nn = (tmp.foreign == false) ? tmp.origin_tree.container.find("li.dragged") : tmp.f_type; + $.each(arr, function(i, val) { + if(tree2.check_move(nn, et, val)) { + mov = val; + ok = true; + return false; + } + }); + if(ok) { + switch(mov) { + case "before": + goTo.y = et_off.top - 2; + tree_component.drag_drop.marker.attr("class","marker"); + break; + case "after": + goTo.y = et_off.top - 2 + tree2.li_height; + tree_component.drag_drop.marker.attr("class","marker"); + break; + case "inside": + goTo.x -= 2; + goTo.y = et_off.top - 2 + tree2.li_height/2; + tree_component.drag_drop.marker.attr("class","marker_plus"); + break; + } + tmp.move_type = mov; + tmp.ref_node = $(event.target); + if(tmp.drag_help !== false) tmp.drag_help.find(".forbidden").removeClass("forbidden"); + tree_component.drag_drop.marker.css({ "left" : goTo.x , "top" : goTo.y }).show(); + } + } + + if( (et.is(".tree") || et.is("ul") ) && et.find("li:eq(0)").size() == 0) { + var et_off = et.offset(); + tmp.move_type = "inside"; + tmp.ref_node = cnt.children("ul:eq(0)"); + if(tmp.drag_help !== false) tmp.drag_help.find(".forbidden").removeClass("forbidden"); + tree_component.drag_drop.marker.attr("class","marker_plus"); + tree_component.drag_drop.marker.css({ "left" : (et_off.left + 10) , "top" : et_off.top + 15 }).show(); + } + else if( (event.target.tagName != "A" && event.target.tagName != "INS") || !ok) { + if(tmp.drag_help !== false) tmp.drag_help.find("li:eq(0) ins").addClass("forbidden"); + tmp.move_type = false; + tmp.ref_node = false; + tree_component.drag_drop.marker.hide(); + } + event.preventDefault(); + event.stopPropagation(); + return false; + } + return true; + }; + $(function () { + $(document).bind("mousemove.jstree", tree_component.mousemove); + $(document).bind("mouseup.jstree", tree_component.mouseup); + }); + + // cut, copy, paste stuff + tree_component.cut_copy = { + copy_nodes : false, + cut_nodes : false + }; + + // css stuff + tree_component.css = false; + tree_component.get_css = function(rule_name, delete_flag) { + rule_name = rule_name.toLowerCase(); + var css_rules = tree_component.css.cssRules || tree_component.css.rules; + var j = 0; + do { + if(css_rules.length && j > css_rules.length + 5) return false; + if(css_rules[j].selectorText && css_rules[j].selectorText.toLowerCase() == rule_name) { + if(delete_flag == true) { + if(tree_component.css.removeRule) document.styleSheets[i].removeRule(j); + if(tree_component.css.deleteRule) document.styleSheets[i].deleteRule(j); + return true; + } + else return css_rules[j]; + } + } + while (css_rules[++j]); + return false; + }; + tree_component.add_css = function(rule_name) { + if(tree_component.get_css(rule_name)) return false; + (tree_component.css.insertRule) ? tree_component.css.insertRule(rule_name + ' { }', 0) : tree_component.css.addRule(rule_name, null, 0); + return tree_component.get_css(rule_name); + }; + tree_component.remove_css = function(rule_name) { + return tree_component.get_css(rule_name, true); + }; + tree_component.add_sheet = function(opts) { + if(opts.str) { + var tmp = document.createElement("style"); + tmp.type = "text/css"; + if(tmp.styleSheet) tmp.styleSheet.cssText = opts.str; + else tmp.appendChild(document.createTextNode(opts.str)); + document.getElementsByTagName("head")[0].appendChild(tmp); + return tmp.sheet; + } + if(opts.url) { + if(document.createStyleSheet) { + try { document.createStyleSheet(opts.url); } catch (e) { }; + } + else { + var newSS = document.createElement('link'); + newSS.rel = 'stylesheet'; + newSS.type = 'text/css'; + newSS.media = "all"; + newSS.href = opts.url; + // var styles = "@import url(' " + url + " ');"; + // newSS.href ='data:text/css,'+escape(styles); + document.getElementsByTagName("head")[0].appendChild(newSS); + return newSS.styleSheet; + } + } + }; + $(function () { + var u = navigator.userAgent.toLowerCase(); + var v = (u.match( /.+(?:rv|it|ra|ie)[\/: ]([\d.]+)/ ) || [0,'0'])[1]; + var css = '/* TREE LAYOUT */ .tree ul { margin:0 0 0 5px; padding:0 0 0 0; list-style-type:none; } .tree li { display:block; min-height:18px; line-height:18px; padding:0 0 0 15px; margin:0 0 0 0; /* Background fix */ clear:both; } .tree li ul { display:none; } .tree li a, .tree li span { display:inline-block;line-height:16px;height:16px;color:black;white-space:nowrap;text-decoration:none;padding:1px 4px 1px 4px;margin:0; } .tree li a:focus { outline: none; } .tree li a input, .tree li span input { margin:0;padding:0 0;display:inline-block;height:12px !important;border:1px solid white;background:white;font-size:10px;font-family:Verdana; } .tree li a input:not([class="xxx"]), .tree li span input:not([class="xxx"]) { padding:1px 0; } /* FOR DOTS */ .tree .ltr li.last { float:left; } .tree > ul li.last { overflow:visible; } /* OPEN OR CLOSE */ .tree li.open ul { display:block; } .tree li.closed ul { display:none !important; } /* FOR DRAGGING */ #jstree-dragged { position:absolute; top:-10px; left:-10px; margin:0; padding:0; } #jstree-dragged ul ul ul { display:none; } #jstree-marker { padding:0; margin:0; line-height:5px; font-size:1px; overflow:hidden; height:5px; position:absolute; left:-45px; top:-30px; z-index:1000; background-color:transparent; background-repeat:no-repeat; display:none; } #jstree-marker.marker { width:45px; background-position:-32px top; } #jstree-marker.marker_plus { width:5px; background-position:right top; } /* BACKGROUND DOTS */ .tree li li { overflow:hidden; } .tree > .ltr > li { display:table; } /* ICONS */ .tree ul ins { display:inline-block; text-decoration:none; width:16px; height:16px; } .tree .ltr ins { margin:0 4px 0 0px; } '; + if(/msie/.test(u) && !/opera/.test(u)) { + if(parseInt(v) == 6) css += '.tree li { height:18px; zoom:1; } .tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); } .marker { width:45px; background-position:-32px top; } .marker_plus { width:5px; background-position:right top; }'; + if(parseInt(v) == 7) css += '.tree li li { overflow:visible; } .tree .ltr li.last { margin-top: expression( (this.previousSibling && /open/.test(this.previousSibling.className) ) ? "-2px" : "0"); }'; + } + if(/opera/.test(u)) css += '.tree > ul > li.last:after { content:"."; display: block; height:1px; clear:both; visibility:hidden; }'; + if(/mozilla/.test(u) && !/(compatible|webkit)/.test(u) && v.indexOf("1.8") == 0) css += '.tree .ltr li a { display:inline; float:left; } .tree li ul { clear:both; }'; + tree_component.css = tree_component.add_sheet({ str : css }); + }); +})(jQuery); + +// Datastores +// HTML and JSON are included here by default +(function ($) { + $.extend($.tree.datastores, { + "html" : function () { + return { + get : function(obj, tree, opts) { + return obj && $(obj).size() ? $('
                    ').append(tree.get_node(obj).clone()).html() : tree.container.children("ul:eq(0)").html(); + }, + parse : function(data, tree, opts, callback) { + if(callback) callback.call(null, data); + return data; + }, + load : function(data, tree, opts, callback) { + if(opts.url) { + $.ajax({ + 'type' : opts.method, + 'url' : opts.url, + 'data' : data, + 'dataType' : "html", + 'success' : function (d, textStatus) { + callback.call(null, d); + }, + 'error' : function (xhttp, textStatus, errorThrown) { + callback.call(null, false); + tree.error(errorThrown + " " + textStatus); + } + }); + } + else { + callback.call(null, opts.static || tree.container.children("ul:eq(0)").html()); + } + } + }; + }, + "json" : function () { + return { + get : function(obj, tree, opts) { + var _this = this; + if(!obj || $(obj).size() == 0) obj = tree.container.children("ul").children("li"); + else obj = $(obj); + + if(!opts) opts = {}; + if(!opts.outer_attrib) opts.outer_attrib = [ "id", "rel", "class" ]; + if(!opts.inner_attrib) opts.inner_attrib = [ ]; + + if(obj.size() > 1) { + var arr = []; + obj.each(function () { + arr.push(_this.get(this, tree, opts)); + }); + return arr; + } + if(obj.size() == 0) return []; + + var json = { attributes : {}, data : {} }; + if(obj.hasClass("open")) json.data.state = "open"; + if(obj.hasClass("closed")) json.data.state = "closed"; + + for(var i in opts.outer_attrib) { + if(!opts.outer_attrib.hasOwnProperty(i)) continue; + var val = (opts.outer_attrib[i] == "class") ? obj.attr(opts.outer_attrib[i]).replace(/(^| )last( |$)/ig," ").replace(/(^| )(leaf|closed|open)( |$)/ig," ") : obj.attr(opts.outer_attrib[i]); + if(typeof val != "undefined" && val.toString().replace(" ","").length > 0) json.attributes[opts.outer_attrib[i]] = val; + delete val; + } + + if(tree.settings.languages.length) { + for(var i in tree.settings.languages) { + if(!tree.settings.languages.hasOwnProperty(i)) continue; + var a = obj.children("a." + tree.settings.languages[i]); + if(opts.force || opts.inner_attrib.length || a.children("ins").get(0).style.backgroundImage.toString().length || a.children("ins").get(0).className.length) { + json.data[tree.settings.languages[i]] = {}; + json.data[tree.settings.languages[i]].title = tree.get_text(obj,tree.settings.languages[i]); + if(a.children("ins").get(0).style.className.length) { + json.data[tree.settings.languages[i]].icon = a.children("ins").get(0).style.className; + } + if(a.children("ins").get(0).style.backgroundImage.length) { + json.data[tree.settings.languages[i]].icon = a.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")",""); + } + if(opts.inner_attrib.length) { + json.data[tree.settings.languages[i]].attributes = {}; + for(var j in opts.inner_attrib) { + if(!opts.inner_attrib.hasOwnProperty(j)) continue; + var val = a.attr(opts.inner_attrib[j]); + if(typeof val != "undefined" && val.toString().replace(" ","").length > 0) json.data[tree.settings.languages[i]].attributes[opts.inner_attrib[j]] = val; + delete val; + } + } + } + else { + json.data[tree.settings.languages[i]] = tree.get_text(obj,tree.settings.languages[i]); + } + } + } + else { + var a = obj.children("a"); + json.data.title = tree.get_text(obj); + + if(a.children("ins").size() && a.children("ins").get(0).className.length) { + json.data.icon = a.children("ins").get(0).className; + } + if(a.children("ins").size() && a.children("ins").get(0).style.backgroundImage.length) { + json.data.icon = a.children("ins").get(0).style.backgroundImage.replace("url(","").replace(")",""); + } + + if(opts.inner_attrib.length) { + json.data.attributes = {}; + for(var j in opts.inner_attrib) { + if(!opts.inner_attrib.hasOwnProperty(j)) continue; + var val = a.attr(opts.inner_attrib[j]); + if(typeof val != "undefined" && val.toString().replace(" ","").length > 0) json.data.attributes[opts.inner_attrib[j]] = val; + delete val; + } + } + } + + if(obj.children("ul").size() > 0) { + json.children = []; + obj.children("ul").children("li").each(function () { + json.children.push(_this.get(this, tree, opts)); + }); + } + return json; + }, + parse : function(data, tree, opts, callback) { + if(Object.prototype.toString.apply(data) === "[object Array]") { + var str = ''; + for(var i = 0; i < data.length; i ++) { + if(typeof data[i] == "function") continue; + str += this.parse(data[i], tree, opts); + } + if(callback) callback.call(null, str); + return str; + } + + if(!data || !data.data) { + if(callback) callback.call(null, false); + return ""; + } + + var str = ''; + str += "
                  •  "; + } + else str += " "; + str += ( (typeof data.data[tree.settings.languages[i]].title).toLowerCase() != "undefined" ? data.data[tree.settings.languages[i]].title : data.data[tree.settings.languages[i]] ) + ""; + } + } + else { + var attr = {}; + attr["href"] = ""; + attr["style"] = ""; + attr["class"] = ""; + if((typeof data.data.attributes).toLowerCase() != "undefined") { + for(var i in data.data.attributes) { + if(!data.data.attributes.hasOwnProperty(i)) continue; + if(i == "style" || i == "class") attr[i] += " " + data.data.attributes[i]; + else attr[i] = data.data.attributes[i]; + } + } + str += " "; + } + else str += " "; + str += ( (typeof data.data.title).toLowerCase() != "undefined" ? data.data.title : data.data ) + ""; + } + if(data.children && data.children.length) { + str += '
                      '; + for(var i = 0; i < data.children.length; i++) { + str += this.parse(data.children[i], tree, opts); + } + str += '
                    '; + } + str += "
                  • "; + if(callback) callback.call(null, str); + return str; + }, + load : function(data, tree, opts, callback) { + if(opts.static) { + callback.call(null, opts.static); + } + else { + $.ajax({ + 'type' : opts.method, + 'url' : opts.url, + 'data' : data, + 'dataType' : "json", + 'success' : function (d, textStatus) { + callback.call(null, d); + }, + 'error' : function (xhttp, textStatus, errorThrown) { + callback.call(null, false); + tree.error(errorThrown + " " + textStatus); + } + }); + } + } + } + } + }); +})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jsTree/plugins/jquery.tree.contextmenu.js b/spec/test_app/public/javascripts/jsTree/plugins/jquery.tree.contextmenu.js new file mode 100755 index 0000000..6401cb3 --- /dev/null +++ b/spec/test_app/public/javascripts/jsTree/plugins/jquery.tree.contextmenu.js @@ -0,0 +1,129 @@ +(function ($) { + $.extend($.tree.plugins, { + "contextmenu" : { + object : $("
                      "), + data : { + t : false, + a : false, + r : false + }, + + defaults : { + class_name : "hover", + items : { + create : { + label : "Create", + icon : "create", + visible : function (NODE, TREE_OBJ) { if(NODE.length != 1) return 0; return TREE_OBJ.check("creatable", NODE); }, + action : function (NODE, TREE_OBJ) { TREE_OBJ.create(false, TREE_OBJ.get_node(NODE[0])); }, + separator_after : true + }, + rename : { + label : "Rename", + icon : "rename", + visible : function (NODE, TREE_OBJ) { if(NODE.length != 1) return false; return TREE_OBJ.check("renameable", NODE); }, + action : function (NODE, TREE_OBJ) { TREE_OBJ.rename(NODE); } + }, + remove : { + label : "Delete", + icon : "remove", + visible : function (NODE, TREE_OBJ) { var ok = true; $.each(NODE, function () { if(TREE_OBJ.check("deletable", this) == false) ok = false; return false; }); return ok; }, + action : function (NODE, TREE_OBJ) { $.each(NODE, function () { TREE_OBJ.remove(this); }); } + } + } + }, + show : function(obj, t) { + var opts = $.extend(true, {}, $.tree.plugins.contextmenu.defaults, t.settings.plugins.contextmenu); + obj = $(obj); + $.tree.plugins.contextmenu.object.empty(); + var str = ""; + var cnt = 0; + for(var i in opts.items) { + if(!opts.items.hasOwnProperty(i)) continue; + if(opts.items[i] === false) continue; + var r = 1; + if(typeof opts.items[i].visible == "function") r = opts.items[i].visible.call(null, $.tree.plugins.contextmenu.data.a, t); + if(r == -1) continue; + else cnt ++; + if(opts.items[i].separator_before === true) str += "
                    •  
                    • "; + str += '
                    • '; + if(opts.items[i].icon) str += " "; + else str += " "; + str += "" + opts.items[i].label + '
                    • '; + if(opts.items[i].separator_after === true) str += "
                    •  
                    • "; + } + var tmp = obj.children("a:visible").offset(); + $.tree.plugins.contextmenu.object.attr("class","tree-context tree-" + t.settings.ui.theme_name.toString() + "-context").html(str); + var h = $.tree.plugins.contextmenu.object.height(); + var w = $.tree.plugins.contextmenu.object.width(); + var x = tmp.left; + var y = tmp.top + parseInt(obj.children("a:visible").height()) + 2; + var max_y = $(window).height() + $(window).scrollTop(); + var max_x = $(window).width() + $(window).scrollLeft(); + if(y + h > max_y) y = Math.max( (max_y - h - 2), 0); + if(x + w > max_x) x = Math.max( (max_x - w - 2), 0); + $.tree.plugins.contextmenu.object.css({ "left" : (x), "top" : (y) }).fadeIn("fast"); + }, + hide : function () { + if(!$.tree.plugins.contextmenu.data.t) return; + var opts = $.extend(true, {}, $.tree.plugins.contextmenu.defaults, $.tree.plugins.contextmenu.data.t.settings.plugins.contextmenu); + if($.tree.plugins.contextmenu.data.r && $.tree.plugins.contextmenu.data.a) { + $.tree.plugins.contextmenu.data.a.children("a, span").removeClass(opts.class_name); + } + $.tree.plugins.contextmenu.data = { a : false, r : false, t : false }; + $.tree.plugins.contextmenu.object.fadeOut("fast"); + }, + exec : function (cmd) { + if($.tree.plugins.contextmenu.data.t == false) return; + var opts = $.extend(true, {}, $.tree.plugins.contextmenu.defaults, $.tree.plugins.contextmenu.data.t.settings.plugins.contextmenu); + try { opts.items[cmd].action.apply(null, [$.tree.plugins.contextmenu.data.a, $.tree.plugins.contextmenu.data.t]); } catch(e) { }; + }, + + callbacks : { + oninit : function () { + if(!$.tree.plugins.contextmenu.css) { + var css = '#jstree-contextmenu { display:none; position:absolute; z-index:2000; list-style-type:none; margin:0; padding:0; left:-2000px; top:-2000px; } .tree-context { margin:20px; padding:0; width:180px; border:1px solid #979797; padding:2px; background:#f5f5f5; list-style-type:none; }.tree-context li { height:22px; margin:0 0 0 27px; padding:0; background:#ffffff; border-left:1px solid #e0e0e0; }.tree-context li a { position:relative; display:block; height:22px; line-height:22px; margin:0 0 0 -28px; text-decoration:none; color:black; padding:0; }.tree-context li a ins { text-decoration:none; float:left; width:16px; height:16px; margin:0 0 0 0; background-color:#f0f0f0; border:1px solid #f0f0f0; border-width:3px 5px 3px 6px; line-height:16px; }.tree-context li a span { display:block; background:#f0f0f0; margin:0 0 0 29px; padding-left:5px; }.tree-context li.separator { background:#f0f0f0; height:2px; line-height:2px; font-size:1px; border:0; margin:0; padding:0; }.tree-context li.separator span { display:block; margin:0px 0 0px 27px; height:1px; border-top:1px solid #e0e0e0; border-left:1px solid #e0e0e0; line-height:1px; font-size:1px; background:white; }.tree-context li a:hover { border:1px solid #d8f0fa; height:20px; line-height:20px; }.tree-context li a:hover span { background:#e7f4f9; margin-left:28px; }.tree-context li a:hover ins { background-color:#e7f4f9; border-color:#e7f4f9; border-width:2px 5px 2px 5px; }.tree-context li a.disabled { color:gray; }.tree-context li a.disabled ins { }.tree-context li a.disabled:hover { border:0; height:22px; line-height:22px; }.tree-context li a.disabled:hover span { background:#f0f0f0; margin-left:29px; }.tree-context li a.disabled:hover ins { border-color:#f0f0f0; background-color:#f0f0f0; border-width:3px 5px 3px 6px; }'; + $.tree.plugins.contextmenu.css = this.add_sheet({ str : css }); + } + }, + onrgtclk : function (n, t, e) { + var opts = $.extend(true, {}, $.tree.plugins.contextmenu.defaults, t.settings.plugins.contextmenu); + n = $(n); + if(n.size() == 0) return; + $.tree.plugins.contextmenu.data.t = t; + if(!n.children("a:eq(0)").hasClass("clicked")) { + $.tree.plugins.contextmenu.data.a = n; + $.tree.plugins.contextmenu.data.r = true; + n.children("a").addClass(opts.class_name); + e.target.blur(); + } + else { + $.tree.plugins.contextmenu.data.r = false; + $.tree.plugins.contextmenu.data.a = (t.selected_arr && t.selected_arr.length > 1) ? t.selected_arr : t.selected; + } + $.tree.plugins.contextmenu.show(n, t); + e.preventDefault(); + e.stopPropagation(); + // return false; // commented out because you might want to do something in your own callback + }, + onchange : function () { $.tree.plugins.contextmenu.hide(); }, + beforedata : function () { $.tree.plugins.contextmenu.hide(); }, + ondestroy : function () { $.tree.plugins.contextmenu.hide(); } + } + } + }); + $(function () { + $.tree.plugins.contextmenu.object.hide().appendTo("body"); + $("#jstree-contextmenu a") + .live("click", function (event) { + if(!$(this).hasClass("disabled")) { + $.tree.plugins.contextmenu.exec.apply(null, [$(this).attr("rel")]); + $.tree.plugins.contextmenu.hide(); + } + event.stopPropagation(); + event.preventDefault(); + return false; + }) + $(document).bind("mousedown", function(event) { if($(event.target).parents("#jstree-contextmenu").size() == 0) $.tree.plugins.contextmenu.hide(); }); + }); +})(jQuery); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jsTree/themes/apple/bg.jpg b/spec/test_app/public/javascripts/jsTree/themes/apple/bg.jpg new file mode 100755 index 0000000000000000000000000000000000000000..3aad05d8fadd75f8d9e02866f695b486f0b46343 GIT binary patch literal 331 zcmex=iF;o{=v;^GnD0RsUZK7IjyJ|1CV5fNcw z8EI*08F@HhWM^mR<>8eO5Ri}(6%>_%OAyQWe}F-dgF%IXk(p7Dfk}{&S&;Gn5r#;h zvzdX8L;}n#9E^7c|G(l-7DfgJMg|=QAOOiQFfqBrF<1it%E1S( literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/jsTree/themes/apple/icons.png b/spec/test_app/public/javascripts/jsTree/themes/apple/icons.png new file mode 100755 index 0000000000000000000000000000000000000000..7923057097be6cb4dfe238a1819d5d504db030da GIT binary patch literal 5951 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 literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/jsTree/themes/apple/style.css b/spec/test_app/public/javascripts/jsTree/themes/apple/style.css new file mode 100755 index 0000000..800c679 --- /dev/null +++ b/spec/test_app/public/javascripts/jsTree/themes/apple/style.css @@ -0,0 +1,34 @@ +/* BACKGROUND */ +.tree-apple .ltr, .tree-apple .rtl { background:url("bg.jpg") left top repeat; min-width:100%; _width:100%; margin-left:0; margin-right:0; display:table; } +.tree-apple .ltr > li.leaf, .tree-apple .rtl > li.leaf { background-image:none; } + +/* LOCKED */ +.tree-apple .locked li a { color:gray; } +/* DOTS */ +.tree-apple ul { background-position:6px 1px; background-repeat:repeat-y; background-image:url(data:image/gif;base64,R0lGODlhAgACAIAAAB4dGf///yH5BAEAAAEALAAAAAACAAIAAAICRF4AOw==); _background-image:url("dot_for_ie.gif"); *background-image:url("dot_for_ie.gif"); } +.tree-apple li { background-position:-64px -16px; background-repeat:no-repeat; background-image:url("icons.png"); } +/* NO DOTS */ +.tree-apple .no_dots, .tree-apple .no_dots ul { background:transparent; } +.tree-apple .no_dots li.leaf { background-image:none; background-color:transparent; } +/* OPEN or CLOSED */ +.tree-apple li.open { background:url("icons.png") -32px -48px no-repeat; } +.tree-apple li.closed, #jstree-dragged.tree-apple li li.open { background:url("icons.png") -48px -32px no-repeat; } +#jstree-marker { background-image:url("icons.png"); } +/* DEFAULT, HOVER, CLICKED, LOADING STATES */ +.tree-apple li a, .tree-apple li span { border-radius:3px; -moz-border-radius:3px; -webkit-border-radius:3px; } +.tree-apple li a:hover, .tree-apple li a.hover, .tree-apple li span { background: #e7f4f9; border:1px solid #d8f0fa; padding:0px 3px 0px 3px; } +.tree-apple li a.clicked, .tree-apple li a.clicked:hover, .tree-apple li span.clicked { background: #beebff; border:1px solid #99defd; padding:0px 3px 0px 3px; } +/* ICONS */ +.tree-apple ins { background-image:url("icons.png"); background-position:0 0; background-repeat:no-repeat; } +.tree-apple ul li a.loading ins { background-image:url("throbber.gif") !important; background-position:0 0 !important; } /* UL is added to make selector stronger */ +.tree-apple li a ins.forbidden { background-position:-16px -16px; } +.tree-apple .locked li a ins { background-position:0 -48px; } +.tree-apple li span ins { background-position:-16px 0; } +#jstree-dragged.tree-apple ins { background:url("icons.png") -16px -32px no-repeat; } +#jstree-dragged.tree-apple ins.forbidden { background:url("icons.png") -16px -16px no-repeat; } + +/* CONTEXT MENU */ +.tree-apple-context a ins { background-image:url("icons.png"); background-repeat:no-repeat; background-position:-64px -64px; } +.tree-apple-context a ins.create { background-position:0 -16px; } +.tree-apple-context a ins.rename { background-position:-16px 0px; } +.tree-apple-context a ins.remove { background-position:0 -32px; } \ No newline at end of file diff --git a/spec/test_app/public/javascripts/jsTree/themes/apple/throbber.gif b/spec/test_app/public/javascripts/jsTree/themes/apple/throbber.gif new file mode 100755 index 0000000000000000000000000000000000000000..95ff649d4162b61d8107adb91ded5940c55e5e4c GIT binary patch literal 1844 zcmb8wYfw{X8VB&hIq%6iIhW)mA`M8L5P~KlG2s@XSob7=AW#Zaq2*E%FqBZJfr`); zkz5dhT$O6^QnjT8MO#30dIMu*M%#|A%sTD#HlrO{wY4p*+gY9IuA49mlMnl4pO4Rn z_x;WPd7pXHw`|t0H$wy>|3Hw(j~{a!_u#>U;o;#sckb-mx%0@8BfgH^ZZ9e-@_0Pg zuV2r}$(fv-G#ZUnRaM>H-N^q_k^f%#w0XNlQvRyMP;G9?-eKOp&iZoY4kYpsKq%iy zk&o$|w5`vk7;@9%)@iXIUrXh`!0$uwMu`MP`H?@4ps7akilJ{bBf@>_s`rfO+$HlE z_Fk&P3xDDyFI)&Q+D0D-t5Ep7fgL^^iyWBJy&O)R%{5h*T2g>V_})by$5BvGMU@al2va{GSn|) zut3aWE?+13Fs?{4V?p|bQq;SOzLD3f;hf_gY5^446Ivm_FQ2l(1VLAR%s)R>i-_ZQ z&)d$DSBFirx$=WL(s}#DvGDnAnm;9cl2)pKO93!>jHXmt^Gus&uhQ^R|DFS#bk;yu zXQ`n@r#qor$^`^cY8FQ%_U9rcuPm(gQQBA0%+xf3slU`~Gl0l3-uhHd@=4~#=fPWD zY4>lysnGXV{#LgVhTk3fb=>k6^YgYHS#f2BMSuUktH3=OTm51ouy8vYGBlb-(_h-$ zl`T>G-3N682cnh$cp#v~5BNys1309lb0K_2N$pK$Z29M+QP)_MmN#_RbW-98UwgS? zP(Boj4P9v56UqUqayN2-d{sv%3*41~dbPL50LqF%%JdK+R7xC!#fqWeXW-SxiQ8bZ+FW zwT7cvr}lqv>zi)X+ZX;N00-P@CGr~Q(Nk-Z6D8fZV4^71JrmZdy}SBcyu*A(s}}8B z*>_$YA((ygq(?jedM-O{83`c}FW|#y)`}6BP)ON|^QFyvv{Weq4FU6?`ljcAY4=EKQf?Yl7+^t|3)Zc4cK^3ZD9J7O$H9Oa)hMNH$W z@k=*@!>0RBjDHb2eQm|uteh_*u1<|TDFHOei>5YV1WV#HL&YfpAw)Y-p3thK`5GMG z00(1a7`AI!Lj`IY{I6y)o0{U&vfI=|Caf!d$6Lq551R6d9|{sz*dJ~P6Lh{Y54JoP zsrA$wQuSgcW!GrmXCe4^8M&3#;ORLlk~aW)orYY_whE^3*yvP*&E-KL%uCQQxDUfx zE37CabE>tCtV^-HQgonXc}nY;y6F*0m5$QyXF{Z2{y{`$pPnJxQ|9NC!JX}UjgzXu z@Se7x*N8V#ZT7CoZ^J}Y<4j?T8h+YunpN?c_Je;6iB;EeXQPV7+Th06 dtwLDJL#a0_K>wk&Y~4#Tit}rd{U6a{{Rfg56CMBn literal 0 HcmV?d00001 diff --git a/spec/test_app/public/javascripts/lang/af.js b/spec/test_app/public/javascripts/lang/af.js new file mode 100644 index 0000000..1e2e21e --- /dev/null +++ b/spec/test_app/public/javascripts/lang/af.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Januarie", + "Februarie", + "Maart", + "April", + "Mei", + "Junie", + "Julie", + "Augustus", + "September", + "Oktober", + "November", + "Desember" + ], + fullDay:[ + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrydag", + "Saterdag", + "Sondag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Vorige maand", + "Volgende maand", + "Vorige jaar", + "Volgende jaar" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/ar.js b/spec/test_app/public/javascripts/lang/ar.js new file mode 100644 index 0000000..602091a --- /dev/null +++ b/spec/test_app/public/javascripts/lang/ar.js @@ -0,0 +1,50 @@ +var fdLocale = { + months:[ + "يناير", + "فبراير", + "مارس", + "أبريل", + "مايو", + "يونيو", + "يوليو", + "أغسطس", + "سبتمبر", + "أكتوبر", + "نوٿمبر", + "ديسمبر" + ], + fullDay:[ + "الاثنين", + "الثلاثاء", + "الأربعاء", + "الخميس", + "الجمعة", + "السبت", + "الأحد" + ], + + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice */ + + + dayAbbr:[ + "الاثنين", + "الثلاثاء", + "الأربعاء", + "الخميس", + "الجمعة", + "السبت", + "الأحد" + ], + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + + titles:[ + "الشهر السابق", + "الشهر المقبل", + "السنة السابقة", + "السنة المقبلة" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/de.js b/spec/test_app/public/javascripts/lang/de.js new file mode 100644 index 0000000..f13de39 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/de.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Januar", + "Februar", + "M\u00e4rz", + "April", + "Mai", + "Juni", + "Juli", + "August", + "September", + "Oktober", + "November", + "Dezember" + ], + fullDay:[ + "Montag", + "Dienstag", + "Mittwoch", + "Donnerstag", + "Freitag", + "Samstag", + "Sonntag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Voriger Monat", + "N\u00e4chst. Monat", + "Voriges Jahr", + "N\u00e4chst. Jahr" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/du.js b/spec/test_app/public/javascripts/lang/du.js new file mode 100644 index 0000000..5d77b6b --- /dev/null +++ b/spec/test_app/public/javascripts/lang/du.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Januari", + "Februari", + "Maart", + "April", + "Mei", + "Juni", + "Juli", + "Augustus", + "September", + "Oktober", + "November", + "December" + ], + fullDay:[ + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrijdag", + "Zaterdag", + "Zondag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Vorige Maand", + "Volgende Maand", + "Vorig jaar", + "Volgend jaar" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/en.js b/spec/test_app/public/javascripts/lang/en.js new file mode 100644 index 0000000..fe5eec4 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/en.js @@ -0,0 +1,42 @@ +var fdLocale = { + months:[ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December" + ], + fullDay:[ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Previous month", + "Next month", + "Previous year", + "Next year", + "Today", + "Show Calendar" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/es.js b/spec/test_app/public/javascripts/lang/es.js new file mode 100644 index 0000000..4aecdcd --- /dev/null +++ b/spec/test_app/public/javascripts/lang/es.js @@ -0,0 +1,41 @@ +var fdLocale = { + months:[ + "Enero", + "Febrero", + "Marzo", + "Abril", + "Mayo", + "Junio", + "Julio", + "Agosto", + "Septiembre", + "Octubre", + "Noviembre", + "Diciembre" + ], + fullDay:[ + "Lunes", + "Martes", + "Mi\u00e9rcoles", + "Jueves", + "Viernes", + "S\u00e1bado", + "Domingo" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Mes Anterior", + "Mes Siguiente", + "A\u00f1o anterior", + "A\u00f1o Siguiente", + "Hoy" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/fi.js b/spec/test_app/public/javascripts/lang/fi.js new file mode 100644 index 0000000..1e204f3 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/fi.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Tammikuu", + "Helmikuu", + "Maaliskuu", + "Huhtikuu", + "Toukokuu", + "Kes\u00e4kuu", + "Hein\u00e4kuu", + "Elokuu", + "Syyskuu", + "Lokakuu", + "Marraskuu", + "Joulukuu" + ], + fullDay:[ + "Maanantai", + "Tiistai", + "Keskiviikko", + "Torstai", + "Perjantai", + "Lauantai", + "Sunnuntai" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Edellinen kuukausi", + "Seuraava kuukausi", + "Edellinen vuosi", + "Seuraava vuosi" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/fr.js b/spec/test_app/public/javascripts/lang/fr.js new file mode 100644 index 0000000..fb524a3 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/fr.js @@ -0,0 +1,44 @@ +var fdLocale = { + months:[ + "Janvier", + "F\u00E9vrier", + "Mars", + "Avril", + "Mai", + "Juin", + "Juillet", + "Ao\u00FBt", + "Septembre", + "Octobre", + "Novembre", + "D\u00E9cembre" + ], + fullDay:[ + "Lundi", + "Mardi", + "Mercredi", + "Jeudi", + "Vendredi", + "Samedi", + "Dimanche" + ], + + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + + titles:[ + "Mois pr\u00E9cedent", + "Mois suivant", + "Ann\u00E9e pr\u00E9cedente", + "Ann\u00E9e suivante", + "Aujourd\u2019hui", + "Voir Calendrier" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/gr.js b/spec/test_app/public/javascripts/lang/gr.js new file mode 100644 index 0000000..8f52c10 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/gr.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Ιανουάριος", + "Φεβρουάριος", + "Μάρτιος", + "Απρίλιος", + "Μάιος", + "Ιούνιος", + "Ιούλιος", + "Αύγουστος", + "Σεπτέμβριος", + "Οκτώβριος", + "Νοέμβριος", + "Δεκέμβριος" + ], + fullDay:[ + "Δευτέρα", + "Τρίτη", + "Τετάρτη", + "Πέμπτη", + "Παρασκευή", + "Σάββατο", + "Κυριακή" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Προηγούμενος μήνας", + "Επόμενος μήνας", + "Προηγούμενη χρόνιά", + "Επόμενη χρονιά" + ] +}; \ No newline at end of file diff --git a/spec/test_app/public/javascripts/lang/he.js b/spec/test_app/public/javascripts/lang/he.js new file mode 100644 index 0000000..8b1167a --- /dev/null +++ b/spec/test_app/public/javascripts/lang/he.js @@ -0,0 +1,49 @@ +var fdLocale = { + months:[ + "ינואר", + "פברואר", + "מרץ", + "אפריל", + "מאי", + "יוני", + "יולי", + "אוגוסט", + "ספטמבר", + "אוקטובר", + "נובמבר", + "דצמבר" + ], + fullDay:[ + "שני", + "שלישי", + "רביעי", + "חמישי", + "שישי", + "שבת", + "ראשון" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + */ + dayAbbr:[ + 'ב', + 'ג', + 'ד', + 'ה', + 'ו', + 'ש', + 'א' + ], + + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + */ + firstDayOfWeek:6, + + titles:[ + "חודש קודם", + "חודש הבא", + "שנה קודמת", + "שנה הבאה", + "היום" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/it.js b/spec/test_app/public/javascripts/lang/it.js new file mode 100644 index 0000000..828f21f --- /dev/null +++ b/spec/test_app/public/javascripts/lang/it.js @@ -0,0 +1,13 @@ +// italian translation by raf + +var fdLocale = { + months:[ "Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre" ], + fullDay:[ "Luned\u00ec", "Marted\u00ec", "Mercoled\u00ec", "Gioved\u00ec", "Venerd\u00ec", "Sabato", "Domenica" ], + /* + Only stipulate the dayAbbr should the first letter of the fullDay not suffice + dayAbbr:[], + Only stipulate the firstDayOfWeek should the first day not be Monday + firstDayOfWeek:0, + */ + titles:[ "Mese Precedente", "Mese Successivo", "Anno Precedente", "Anno Successivo", "Oggi" ] +}; diff --git a/spec/test_app/public/javascripts/lang/nl.js b/spec/test_app/public/javascripts/lang/nl.js new file mode 100644 index 0000000..5d77b6b --- /dev/null +++ b/spec/test_app/public/javascripts/lang/nl.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Januari", + "Februari", + "Maart", + "April", + "Mei", + "Juni", + "Juli", + "Augustus", + "September", + "Oktober", + "November", + "December" + ], + fullDay:[ + "Maandag", + "Dinsdag", + "Woensdag", + "Donderdag", + "Vrijdag", + "Zaterdag", + "Zondag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Vorige Maand", + "Volgende Maand", + "Vorig jaar", + "Volgend jaar" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/no.js b/spec/test_app/public/javascripts/lang/no.js new file mode 100644 index 0000000..1a1186a --- /dev/null +++ b/spec/test_app/public/javascripts/lang/no.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Januar", + "Februar", + "Mars", + "April", + "Mai", + "Juni", + "Juli", + "August", + "September", + "Oktober", + "November", + "Desember" + ], + fullDay:[ + "Mandag", + "Tirsdag", + "Onsdag", + "Torsdag", + "Fredag", + "L\u00f8rdag", + "S\u00f8ndag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Forrige m\u00e5ned", + "Neste m\u00e5ned", + "Forrige \u00e5r", + "Neste \u00e5r" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/pt.js b/spec/test_app/public/javascripts/lang/pt.js new file mode 100644 index 0000000..ccd7733 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/pt.js @@ -0,0 +1,50 @@ +var fdLocale = { + months:[ + "Janeiro", + "Fevereiro", + "Mar\u00E7o", + "Abril", + "Maio", + "Junho", + "Julho", + "Agosto", + "Setembro", + "Outubro", + "Novembro", + "Dezembro" + ], + fullDay:[ + "Segunda", + "Ter\u00E7a", + "Quarta", + "Quinta", + "Sexta", + "S\u00E1bado", + "Domingo" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + dayAbbr:["Seg", + "Ter", + "Qua", + "Qui", + "Sex", + "Sab", + "Dom"], + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + firstDayOfWeek:6, + titles:[ + "M\u00EAs anterior", + "Pr\u00F3ximo m\u00EAs", + "Ano anterior", + "Pr\u00F3ximo ano", + "Hoje", + "Exibir calend\u00E1rio" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/ro.js b/spec/test_app/public/javascripts/lang/ro.js new file mode 100644 index 0000000..6d80161 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/ro.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Ianuarie", + "Februarie", + "Martie", + "Aprilie", + "Mai", + "Iunie", + "Iulie", + "August", + "Septembrie", + "Octombrie", + "Noiembrie", + "Decembrie" + ], + fullDay:[ + "Luni", + "Mar\u0163i", + "Miercuri", + "Joi", + "Vineri", + "S\u00e2mb\u00e3t\u00e3", + "Duminic\u00e3" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Luna anterioar\u00e3", + "Luna urm\u00e3toare", + "Anul anterior", + "Anul urm\u00e3tor" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/ru.js b/spec/test_app/public/javascripts/lang/ru.js new file mode 100644 index 0000000..d45f224 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/ru.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Январь", + "Февраль", + "Март", + "Апрель", + "Май", + "Июнь", + "Июль", + "Август", + "Сентябрь", + "Октябрь", + "Ноябрь", + "Декабрь" + ], + fullDay:[ + "Понедельник", + "Вторник", + "Среда", + "Четверг", + "Пятница", + "Суббота", + "Воскресенье" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Предыдущий месяц", + "Следующий месяц", + "Предыдущий год", + "Следующий год" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/sp.js b/spec/test_app/public/javascripts/lang/sp.js new file mode 100644 index 0000000..ecfd7dc --- /dev/null +++ b/spec/test_app/public/javascripts/lang/sp.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Enero", + "Febrero", + "Marzo", + "Abril", + "Mayo", + "Junio", + "Julio", + "Agosto", + "Septiembre", + "Octubre", + "Noviembre", + "Diciembre" + ], + fullDay:[ + "Lunes", + "Martes", + "Mi\u00e9rcoles", + "Jueves", + "Viernes", + "S\u00e1bado", + "Domingo" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Mes Anterior", + "Mes Siguiente", + "A\u00f1o Anterior", + "A\u00f1o Siguiente" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/sv.js b/spec/test_app/public/javascripts/lang/sv.js new file mode 100644 index 0000000..3c5c2a1 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/sv.js @@ -0,0 +1,41 @@ +// Swedish +var fdLocale = { + months:[ + "Januari", + "Februari", + "Mars", + "April", + "Maj", + "Juni", + "Juli", + "Augusti", + "September", + "Oktober", + "November", + "December" + ], + fullDay:[ + "M\u00e5ndag", + "Tisdag", + "Onsdag", + "Torsdag", + "Fredag", + "L\u00f6rdag", + "S\u00f6ndag" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "F\u00f6reg\u00e5ende m\u00e5nad", + "N\u00e4sta m\u00e5nad", + "F\u00f6reg\u00e5ende \u00e5r", + "N\u00e4sta \u00e5r" + ] +}; diff --git a/spec/test_app/public/javascripts/lang/ua.js b/spec/test_app/public/javascripts/lang/ua.js new file mode 100644 index 0000000..9aa2fb6 --- /dev/null +++ b/spec/test_app/public/javascripts/lang/ua.js @@ -0,0 +1,40 @@ +var fdLocale = { + months:[ + "Січень", + "Лютий", + "Березень", + "Квітень", + "Травень", + "Червень", + "Липень", + "Серпень", + "Вересень", + "Жовтень", + "Листопад", + "Грудень" + ], + fullDay:[ + "Понеділок", + "Вівторок", + "Середа", + "Четвер", + "П'ятниця", + "Субота", + "Неділя" + ], + /* Only stipulate the dayAbbr should the first letter of the fullDay not suffice + + dayAbbr:[], + */ + + /* Only stipulate the firstDayOfWeek should the first day not be Monday + + firstDayOfWeek:0, + */ + titles:[ + "Попередній місяць", + "Наступний місяць", + "Попередній рік", + "Наступний рік" + ] +}; \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_cn.js b/spec/test_app/public/javascripts/localization/messages_cn.js new file mode 100644 index 0000000..f24f5a4 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_cn.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: CN + * Author: Fayland Lam + */ +jQuery.extend(jQuery.validator.messages, { + required: "必选字段", + remote: "请修正该字段", + email: "请输入正确格式的电子邮件", + url: "请输入合法的网址", + date: "请输入合法的日期", + dateISO: "请输入合法的日期 (ISO).", + number: "请输入合法的数字", + digits: "只能输入整数", + creditcard: "请输入合法的信用卡号", + equalTo: "请再次输入相同的值", + accept: "请输入拥有合法后缀名的字符串", + maxlength: jQuery.validator.format("请输入一个长度最多是 {0} 的字符串"), + minlength: jQuery.validator.format("请输入一个长度最少是 {0} 的字符串"), + rangelength: jQuery.validator.format("请输入一个长度介于 {0} 和 {1} 之间的字符串"), + range: jQuery.validator.format("请输入一个介于 {0} 和 {1} 之间的值"), + max: jQuery.validator.format("请输入一个最大为 {0} 的值"), + min: jQuery.validator.format("请输入一个最小为 {0} 的值") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_cs.js b/spec/test_app/public/javascripts/localization/messages_cs.js new file mode 100644 index 0000000..f5391da --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_cs.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: CS + */ +jQuery.extend(jQuery.validator.messages, { + required: "Tento údaj je povinný.", + remote: "Prosím, opravte tento údaj.", + email: "Prosím, zadejte platný e-mail.", + url: "Prosím, zadejte platné URL.", + date: "Prosím, zadejte platné datum.", + dateISO: "Prosím, zadejte platné datum (ISO).", + number: "Prosím, zadejte číslo.", + digits: "Prosím, zadávejte pouze číslice.", + creditcard: "Prosím, zadejte číslo kreditní karty.", + equalTo: "Prosím, zadejte znovu stejnou hodnotu.", + accept: "Prosím, zadejte soubor se správnou příponou.", + maxlength: jQuery.validator.format("Prosím, zadejte nejvíce {0} znaků."), + minlength: jQuery.validator.format("Prosím, zadejte nejméně {0} znaků."), + rangelength: jQuery.validator.format("Prosím, zadejte od {0} do {1} znaků."), + range: jQuery.validator.format("Prosím, zadejte hodnotu od {0} do {1}."), + max: jQuery.validator.format("Prosím, zadejte hodnotu menší nebo rovnu {0}."), + min: jQuery.validator.format("Prosím, zadejte hodnotu větší nebo rovnu {0}.") +}); diff --git a/spec/test_app/public/javascripts/localization/messages_da.js b/spec/test_app/public/javascripts/localization/messages_da.js new file mode 100644 index 0000000..3736d96 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_da.js @@ -0,0 +1,21 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: DA + * Skipped date/dateISO/number. + */ +jQuery.extend(jQuery.validator.messages, { + required: "Dette felt er påkrævet.", + maxlength: jQuery.validator.format("Indtast højst {0} tegn."), + minlength: jQuery.validator.format("Indtast mindst {0} tegn."), + rangelength: jQuery.validator.format("Indtast mindst {0} og højst {1} tegn."), + email: "Indtast en gyldig email-adresse.", + url: "Indtast en gyldig URL.", + dateDE: "Indtast en gyldig dato.", + numberDE: "Indtast et tal.", + digits: "Indtast kun cifre.", + equalTo: "Indtast den samme værdi igen.", + range: jQuery.validator.format("Angiv en værdi mellem {0} og {1}."), + max: jQuery.validator.format("Angiv en værdi der højst er {0}."), + min: jQuery.validator.format("Angiv en værdi der mindst er {0}."), + creditcard: "Indtast et gyldigt kreditkortnummer." +}); diff --git a/spec/test_app/public/javascripts/localization/messages_de.js b/spec/test_app/public/javascripts/localization/messages_de.js new file mode 100644 index 0000000..5c1a5b3 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_de.js @@ -0,0 +1,21 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: DE + * Skipped date/dateISO/number. + */ +jQuery.extend(jQuery.validator.messages, { + required: "Dieses Feld ist ein Pflichtfeld.", + maxlength: jQuery.validator.format("Geben Sie bitte maximal {0} Zeichen ein."), + minlength: jQuery.validator.format("Geben Sie bitte mindestens {0} Zeichen ein."), + rangelength: jQuery.validator.format("Geben Sie bitte mindestens {0} und maximal {1} Zeichen ein."), + email: "Geben Sie bitte eine gültige E-Mail Adresse ein.", + url: "Geben Sie bitte eine gültige URL ein.", + dateDE: "Bitte geben Sie ein gültiges Datum ein.", + numberDE: "Geben Sie bitte eine Nummer ein.", + digits: "Geben Sie bitte nur Ziffern ein.", + equalTo: "Bitte denselben Wert wiederholen.", + range: jQuery.validator.format("Geben Sie bitten einen Wert zwischen {0} und {1}."), + max: jQuery.validator.format("Geben Sie bitte einen Wert kleiner oder gleich {0} ein."), + min: jQuery.validator.format("Geben Sie bitte einen Wert größer oder gleich {0} ein."), + creditcard: "Geben Sie bitte ein gültige Kreditkarten-Nummer ein." +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_es.js b/spec/test_app/public/javascripts/localization/messages_es.js new file mode 100644 index 0000000..28262c0 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_es.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: ES + * Author: David Esperalta - http://www.dec.gesbit.com/ + */ +jQuery.extend(jQuery.validator.messages, { + required: "Este campo es obligatorio.", + remote: "Por favor, rellena esta campo.", + email: "Por favor, escribe una dirección de correo válida", + url: "Por favor, escribe una URL válida.", + date: "Por favor, escribe una fecha válida.", + dateISO: "Por favor, escribe una fecha (ISO) válida.", + number: "Por favor, escribe un número entero válido.", + digits: "Por favor, escribe sólo dígitos.", + creditcard: "Por favor, escribe un número de tarjeta válido.", + equalTo: "Por favor, escribe el mismo valor de nuevo.", + accept: "Por favor, escribe una valor con una extensión aceptada.", + maxlength: jQuery.validator.format("Por favor, no escribas más de {0} caracteres."), + minlength: jQuery.validator.format("Por favor, no escribas menos de {0} caracteres."), + rangelength: jQuery.validator.format("Por favor, escribe un valor entre {0} y {1} caracteres."), + range: jQuery.validator.format("Por favor, escribe un valor entre {0} y {1}."), + max: jQuery.validator.format("Por favor, escribe un valor igual o menor que {0}."), + min: jQuery.validator.format("Por favor, escribe un valor igual o mayor que {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_fr.js b/spec/test_app/public/javascripts/localization/messages_fr.js new file mode 100644 index 0000000..9825dbe --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_fr.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: FR + */ +jQuery.extend(jQuery.validator.messages, { + required: "Ce champ est requis.", + remote: "Veuillez remplir ce champ pour continuer.", + email: "Veuillez entrer une adresse email valide.", + url: "Veuillez entrer une URL valide.", + date: "Veuillez entrer une date valide.", + dateISO: "Veuillez entrer une date valide (ISO).", + number: "Veuillez entrer un nombre valide.", + digits: "Veuillez entrer (seulement) une valeur numérique.", + creditcard: "Veuillez entrer un numéro de carte de crédit valide.", + equalTo: "Veuillez entrer une nouvelle fois la même valeur.", + accept: "Veuillez entrer une valeur avec une extension valide.", + maxlength: jQuery.validator.format("Veuillez ne pas entrer plus de {0} caractères."), + minlength: jQuery.validator.format("Veuillez entrer au moins {0} caractères."), + rangelength: jQuery.validator.format("Veuillez entrer entre {0} et {1} caractères."), + range: jQuery.validator.format("Veuillez entrer une valeur entre {0} et {1}."), + max: jQuery.validator.format("Veuillez entrer une valeur inférieure ou égale à {0}."), + min: jQuery.validator.format("Veuillez entrer une valeur supérieure ou égale à {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_hu.js b/spec/test_app/public/javascripts/localization/messages_hu.js new file mode 100644 index 0000000..ba42340 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_hu.js @@ -0,0 +1,21 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: HU + * Skipped dateISO/DE, numberDE + */ +jQuery.extend(jQuery.validator.messages, { + required: "Kötelező megadni.", + maxlength: jQuery.validator.format("Legfeljebb {0} karakter hosszú legyen."), + minlength: jQuery.validator.format("Legalább {0} karakter hosszú legyen."), + rangelength: jQuery.validator.format("Legalább {0} és legfeljebb {1} karakter hosszú legyen."), + email: "Érvényes e-mail címnek kell lennie.", + url: "Érvényes URL-nek kell lennie.", + date: "Dátumnak kell lennie.", + number: "Számnak kell lennie.", + digits: "Csak számjegyek lehetnek.", + equalTo: "Meg kell egyeznie a két értéknek.", + range: jQuery.validator.format("{0} és {1} közé kell esnie."), + max: jQuery.validator.format("Nem lehet nagyobb, mint {0}."), + min: jQuery.validator.format("Nem lehet kisebb, mint {0}."), + creditcard: "Érvényes hitelkártyaszámnak kell lennie." +}); diff --git a/spec/test_app/public/javascripts/localization/messages_it.js b/spec/test_app/public/javascripts/localization/messages_it.js new file mode 100644 index 0000000..a4669d4 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_it.js @@ -0,0 +1,26 @@ +/* + * Traduzione dei messaggi di default per il pugin jQuery validation. + * Language: IT + * Traduzione a cura di Davide Falchetto + * E-mail: d.falchetto@d4solutions.it + * Web: www.d4solutions.it + */ +jQuery.extend(jQuery.validator.messages, { + required: "Campo obbligatorio.", + remote: "Controlla questo campo.", + email: "Inserisci un indirizzo email valido.", + url: "Inserisci un indirizzo web valido.", + date: "Inserisci una data valida.", + dateISO: "Inserisci una data valida (ISO).", + number: "Inserisci un numero valido.", + digits: "Inserisci solo numeri.", + creditcard: "Inserisci un numero di carta di credito valido.", + equalTo: "Il valore non corrisponde.", + accept: "Inserisci un valore con un'estensione valida.", + maxlength: jQuery.validator.format("Non inserire più di {0} caratteri."), + minlength: jQuery.validator.format("Inserisci almeno {0} caratteri."), + rangelength: jQuery.validator.format("Inserisci un valore compreso tra {0} e {1} caratteri."), + range: jQuery.validator.format("Inserisci un valore compreso tra {0} e {1}."), + max: jQuery.validator.format("Inserisci un valore minore o uguale a {0}."), + min: jQuery.validator.format("Inserisci un valore maggiore o uguale a {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_kk.js b/spec/test_app/public/javascripts/localization/messages_kk.js new file mode 100644 index 0000000..2e93fc3 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_kk.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: KK + */ +jQuery.extend(jQuery.validator.messages, { + required: "Бұл өрісті міндетті түрде толтырыңыз.", + remote: "Дұрыс мағына енгізуіңізді сұраймыз.", + email: "Нақты электронды поштаңызды енгізуіңізді сұраймыз.", + url: "Нақты URL-ды енгізуіңізді сұраймыз.", + date: "Нақты URL-ды енгізуіңізді сұраймыз.", + dateISO: "Нақты ISO форматымен сәйкес датасын енгізуіңізді сұраймыз.", + number: "Күнді енгізуіңізді сұраймыз.", + digits: "Тек қана сандарды енгізуіңізді сұраймыз.", + creditcard: "Несие картасының нөмірін дұрыс енгізуіңізді сұраймыз.", + equalTo: "Осы мәнді қайта енгізуіңізді сұраймыз.", + accept: "Файлдың кеңейтуін дұрыс таңдаңыз.", + maxlength: jQuery.format("Ұзындығы {0} символдан көр болмасын."), + minlength: jQuery.format("Ұзындығы {0} символдан аз болмасын."), + rangelength: jQuery.format("Ұзындығы {0}-{1} дейін мән енгізуіңізді сұраймыз."), + range: jQuery.format("Пожалуйста, введите число от {0} до {1}. - {0} - {1} санын енгізуіңізді сұраймыз."), + max: jQuery.format("{0} аз немесе тең санын енгізуіңіді сұраймыз."), + min: jQuery.format("{0} көп немесе тең санын енгізуіңізді сұраймыз.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_nl.js b/spec/test_app/public/javascripts/localization/messages_nl.js new file mode 100644 index 0000000..d967637 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_nl.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: NL + */ +jQuery.extend(jQuery.validator.messages, { + required: "Dit is een verplicht veld.", + remote: "Controleer dit veld.", + email: "Vul hier een geldig email adres in.", + url: "Vul hier een geldige URL in.", + date: "Vul hier een geldige datum in.", + dateISO: "Vul hier een geldige datum in (ISO).", + number: "Vul hier een geldig nummer in.", + digits: "Vul hier alleen nummers in.", + creditcard: "Vul hier een geldig credit card nummer in.", + equalTo: "Vul hier dezelfde waarde in.", + accept: "Vul hier een waarde in met een geldige extensie.", + maxlength: jQuery.validator.format("Vul hier maximaal {0} tekens in."), + minlength: jQuery.validator.format("Vul hier minimaal {0} tekens in."), + rangelength: jQuery.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1} tekens."), + range: jQuery.validator.format("Vul hier een waarde in van minimaal {0} en maximaal {1}."), + max: jQuery.validator.format("Vul hier een waarde in kleiner dan of gelijk aan {0}."), + min: jQuery.validator.format("Vul hier een waarde in groter dan of gelijk aan {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_no.js b/spec/test_app/public/javascripts/localization/messages_no.js new file mode 100644 index 0000000..44bfde3 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_no.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: NO (Norwegian) + */ +jQuery.extend(jQuery.validator.messages, { + required: "Dette feltet er obligatorisk.", + maxlength: jQuery.validator.format("Maksimalt {0} tegn."), + minlength: jQuery.validator.format("Minimum {0} tegn."), + rangelength: jQuery.validator.format("Angi minimum {0} og maksimum {1} tegn."), + email: "Oppgi en gyldig epostadresse.", + url: "Angi en gyldig URL.", + date: "Angi en gyldig dato.", + dateISO: "Angi en gyldig dato (&ARING;&ARING;&ARING;&ARING;-MM-DD).", + dateSE: "Angi en gyldig dato.", + number: "Angi et gyldig nummer.", + numberSE: "Angi et gyldig nummer.", + digits: "Skriv kun tall.", + equalTo: "Skriv samme verdi igjen.", + range: jQuery.validator.format("Angi en verdi mellom {0} og {1}."), + max: jQuery.validator.format("Angi en verdi som er større eller lik {0}."), + min: jQuery.validator.format("Angi en verdi som er mindre eller lik {0}."), + creditcard: "Angi et gyldig kredittkortnummer." +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_pl.js b/spec/test_app/public/javascripts/localization/messages_pl.js new file mode 100644 index 0000000..b8a1bfd --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_pl.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: PL + */ +jQuery.extend(jQuery.validator.messages, { + required: "To pole jest wymagane.", + remote: "Proszę o wypełnienie tego pola.", + email: "Proszę o podanie prawidłowego adresu email.", + url: "Proszę o podanie prawidłowego URL.", + date: "Proszę o podanie prawidłowej daty.", + dateISO: "Proszę o podanie prawidłowej daty (ISO).", + number: "Proszę o podanie prawidłowej liczby.", + digits: "Proszę o podanie samych cyfr.", + creditcard: "Proszę o podanie prawidłowej karty kredytowej.", + equalTo: "Proszę o podanie tej samej wartości ponownie.", + accept: "Proszę o podanie wartości z prawidłowym rozszerzeniem.", + maxlength: jQuery.validator.format("Proszę o podanie nie więcej niż {0} znaków."), + minlength: jQuery.validator.format("Proszę o podanie przynajmniej {0} znaków."), + rangelength: jQuery.validator.format("Proszę o podanie wartości o długości od {0} do {1} znaków."), + range: jQuery.validator.format("Proszę o podanie wartości z przedziału od {0} do {1}."), + max: jQuery.validator.format("Proszę o podanie wartości mniejszej bądź równej {0}."), + min: jQuery.validator.format("Proszę o podanie wartości większej bądź równej {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_ptbr.js b/spec/test_app/public/javascripts/localization/messages_ptbr.js new file mode 100644 index 0000000..1575dcf --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_ptbr.js @@ -0,0 +1,30 @@ +/** + * Translated default messages for the jQuery validation plugin. + * Language: PT_BR + * Translator: Francisco Ernesto Teixeira + */ +jQuery.extend(jQuery.validator.messages, { + required: "Este campo é requerido.", + remote: "Por favor, corrija este campo.", + email: "Por favor, forneça um endereço eletrônico válido.", + url: "Por favor, forneça uma URL válida.", + date: "Por favor, forneça uma data válida.", + dateISO: "Por favor, forneça uma data válida (ISO).", + dateDE: "Bitte geben Sie ein gültiges Datum ein.", + number: "Por favor, forneça um número válida.", + numberDE: "Bitte geben Sie eine Nummer ein.", + digits: "Por favor, forneça somente dígitos.", + creditcard: "Por favor, forneça um cartão de crédito válido.", + equalTo: "Por favor, forneça o mesmo valor novamente.", + accept: "Por favor, forneça um valor com uma extensão válida.", + maxlength: jQuery.validator.format("Por favor, forneça não mais que {0} caracteres."), + minlength: jQuery.validator.format("Por favor, forneça ao menos {0} caracteres."), + rangelength: jQuery.validator.format("Por favor, forneça um valor entre {0} e {1} caracteres de comprimento."), + range: jQuery.validator.format("Por favor, forneça um valor entre {0} e {1}."), + max: jQuery.validator.format("Por favor, forneça um valor menor ou igual a {0}."), + min: jQuery.validator.format("Por favor, forneça um valor maior ou igual a {0}.") +}); + +jQuery.validator.addMethod("datePTBR", function(value) { + return this.optional(element) || /^\d\d?\/\d\d?\/\d\d\d?\d?$/.test(value); +}, "Por favor, forneça uma data válida."); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_ro.js b/spec/test_app/public/javascripts/localization/messages_ro.js new file mode 100644 index 0000000..d45adba --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_ro.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: RO + * Author: Elzo Valugi - http://www.valugi.ro + */ +jQuery.extend(jQuery.validator.messages, { + required: "Acest câmp este obligatoriu.", + remote: "Te rugăm să completezi acest câmp.", + email: "Te rugăm să introduci o adresă de email validă", + url: "Te rugăm sa introduci o adresă URL validă.", + date: "Te rugăm să introduci o dată corectă.", + dateISO: "Te rugăm să introduci o dată (ISO) corectă.", + number: "Te rugăm să introduci un număr întreg valid.", + digits: "Te rugăm să introduci doar cifre.", + creditcard: "Te rugăm să introduci un numar de carte de credit valid.", + equalTo: "Te rugăm să reintroduci valoarea.", + accept: "Te rugăm să introduci o valoare cu o extensie validă.", + maxlength: jQuery.validator.format("Te rugăm să nu introduci mai mult de {0} caractere."), + minlength: jQuery.validator.format("Te rugăm să introduci cel puțin {0} caractere."), + rangelength: jQuery.validator.format("Te rugăm să introduci o valoare între {0} și {1} caractere."), + range: jQuery.validator.format("Te rugăm să introduci o valoare între {0} și {1}."), + max: jQuery.validator.format("Te rugăm să introduci o valoare egal sau mai mică decât {0}."), + min: jQuery.validator.format("Te rugăm să introduci o valoare egal sau mai mare decât {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_ru.js b/spec/test_app/public/javascripts/localization/messages_ru.js new file mode 100644 index 0000000..6685cdc --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_ru.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: RU + */ +jQuery.extend(jQuery.validator.messages, { + required: "Это поле необходимо заполнить.", + remote: "Пожалуйста, введите правильное значение.", + email: "Пожалуйста, введите корретный адрес электронной почты.", + url: "Пожалуйста, введите корректный URL.", + date: "Пожалуйста, введите корректную дату.", + dateISO: "Пожалуйста, введите корректную дату в формате ISO.", + number: "Пожалуйста, введите число.", + digits: "Пожалуйста, вводите только цифры.", + creditcard: "Пожалуйста, введите правильный номер кредитной карты.", + equalTo: "Пожалуйста, введите такое же значение ещё раз.", + accept: "Пожалуйста, выберите файл с правильным расширением.", + maxlength: jQuery.validator.format("Пожалуйста, введите не больше {0} символов."), + minlength: jQuery.validator.format("Пожалуйста, введите не меньше {0} символов."), + rangelength: jQuery.validator.format("Пожалуйста, введите значение длиной от {0} до {1} символов."), + range: jQuery.validator.format("Пожалуйста, введите число от {0} до {1}."), + max: jQuery.validator.format("Пожалуйста, введите число, меньшее или равное {0}."), + min: jQuery.validator.format("Пожалуйста, введите число, большее или равное {0}.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_se.js b/spec/test_app/public/javascripts/localization/messages_se.js new file mode 100644 index 0000000..94ee02d --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_se.js @@ -0,0 +1,23 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: SE + */ +jQuery.extend(jQuery.validator.messages, { + required: "Detta fält är obligatoriskt.", + maxlength: jQuery.validator.format("Du får ange högst {0} tecken."), + minlength: jQuery.validator.format("Du måste ange minst {0} tecken."), + rangelength: jQuery.validator.format("Ange minst {0} och max {1} tecken."), + email: "Ange en korrekt e-postadress.", + url: "Ange en korrekt URL.", + date: "Ange ett korrekt datum.", + dateISO: "Ange ett korrekt datum (&ARING;&ARING;&ARING;&ARING;-MM-DD).", + dateSE: "Ange ett korrekt datum.", + number: "Ange ett korrekt nummer.", + numberSE: "Ange ett korrekt nummer.", + digits: "Ange endast siffror.", + equalTo: "Ange samma värde igen.", + range: jQuery.validator.format("Ange ett värde mellan {0} och {1}."), + max: jQuery.validator.format("Ange ett värde som är större eller lika med {0}."), + min: jQuery.validator.format("Ange ett värde som är mindre eller lika med {0}."), + creditcard: "Ange ett korrekt kreditkortsnummer." +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_sk.js b/spec/test_app/public/javascripts/localization/messages_sk.js new file mode 100644 index 0000000..151e513 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_sk.js @@ -0,0 +1,21 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: SK + * Skipped dateISO/DE, numberDE + */ +jQuery.extend(jQuery.validator.messages, { + required: "Povinné zadať.", + maxlength: jQuery.validator.format("Maximálne {0} znakov."), + minlength: jQuery.validator.format("Minimálne {0} znakov."), + rangelength: jQuery.validator.format("Minimálne {0} a Maximálne {0} znakov."), + email: "E-mailová adresa musí byť platná.", + url: "URL musí byť platný.", + date: "Musí byť dátum.", + number: "Musí byť číslo.", + digits: "Môže obsahovať iba číslice.", + equalTo: "Dva hodnoty sa musia rovnať.", + range: jQuery.validator.format("Musí byť medzi {0} a {1}."), + max: jQuery.validator.format("Nemôže byť viac ako{0}."), + min: jQuery.validator.format("Nemôže byť menej ako{0}."), + creditcard: "Číslo platobnej karty musí byť platné." +}); diff --git a/spec/test_app/public/javascripts/localization/messages_tr.js b/spec/test_app/public/javascripts/localization/messages_tr.js new file mode 100644 index 0000000..aca5cdf --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_tr.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: TR + * Author: kara + */ +jQuery.extend(jQuery.validator.messages, { + required: "Bu alanın doldurulması zorunludur.", + remote: "Lütfen bu alanı düzeltin.", + email: "Lütfen geçerli bir e-posta adresi giriniz.", + url: "Lütfen geçerli bir web adresi (URL) giriniz.", + date: "Lütfen geçerli bir tarih giriniz.", + dateISO: "Lütfen geçerli bir tarih giriniz(ISO formatında)", + number: "Lütfen geçerli bir sayı giriniz.", + digits: "Lütfen sadece sayısal karakterler giriniz.", + creditcard: "Lütfen geçerli bir kredi kartı giriniz.", + equalTo: "Lütfen aynı değeri tekrar giriniz.", + accept: "Lütfen geçerli uzantıya sahip bir değer giriniz.", + maxlength: jQuery.validator.format("Lütfen en fazla {0} karakter uzunluğunda bir değer giriniz."), + minlength: jQuery.validator.format("Lütfen en az {0} karakter uzunluğunda bir değer giriniz."), + rangelength: jQuery.validator.format("Lütfen en az {0} ve en fazla {1} uzunluğunda bir değer giriniz."), + range: jQuery.validator.format("Lütfen {0} ile {1} arasında bir değer giriniz."), + max: jQuery.validator.format("Lütfen {0} değerine eşit ya da daha küçük bir değer giriniz."), + min: jQuery.validator.format("Lütfen {0} değerine eşit ya da daha büyük bir değer giriniz.") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_tw.js b/spec/test_app/public/javascripts/localization/messages_tw.js new file mode 100644 index 0000000..027de64 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_tw.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: TW (Taiwan - Traditional Chinese) + * Author: Mr.BB + */ +jQuery.extend(jQuery.validator.messages, { + required: "必填", + remote: "請修正此欄位", + email: "請輸入正確的電子信箱", + url: "請輸入合法的URL", + date: "請輸入合法的日期", + dateISO: "請輸入合法的日期 (ISO).", + number: "請輸入數字", + digits: "請輸入整數", + creditcard: "請輸入合法的信用卡號碼", + equalTo: "請重複輸入一次", + accept: "請輸入有效的後缀字串", + maxlength: jQuery.validator.format("請輸入長度不大於{0} 的字串"), + minlength: jQuery.validator.format("請輸入長度不小於 {0} 的字串"), + rangelength: jQuery.validator.format("請輸入長度介於 {0} 和 {1} 之間的字串"), + range: jQuery.validator.format("請輸入介於 {0} 和 {1} 之間的數值"), + max: jQuery.validator.format("請輸入不大於 {0} 的數值"), + min: jQuery.validator.format("請輸入不小於 {0} 的數值") +}); \ No newline at end of file diff --git a/spec/test_app/public/javascripts/localization/messages_ua.js b/spec/test_app/public/javascripts/localization/messages_ua.js new file mode 100644 index 0000000..fa084a1 --- /dev/null +++ b/spec/test_app/public/javascripts/localization/messages_ua.js @@ -0,0 +1,24 @@ +/* + * Translated default messages for the jQuery validation plugin. + * Language: UA (Ukrainian) + * Author: maserg + */ +jQuery.extend(jQuery.validator.messages, { + required: "Це поле необхідно заповнити.", + remote: "Будь ласка, введіть правильне значення.", + email: "Будь ласка, введіть коректну адресу електронної пошти.", + url: "Будь ласка, введіть коректний URL.", + date: "Будь ласка, введіть коректну дату.", + dateISO: "Будь ласка, введіть коректну дату у форматі ISO.", + number: "Будь ласка, введіть число.", + digits: "Вводите потрібно лише цифри.", + creditcard: "Будь ласка, введіть правильний номер кредитної карти.", + equalTo: "Будь ласка, введіть таке ж значення ще раз.", + accept: "Будь ласка, виберіть файл з правильним розширенням.", + maxlength: jQuery.validator.format("Будь ласка, введіть не більше {0} символів."), + minlength: jQuery.validator.format("Будь ласка, введіть не менше {0} символів."), + rangelength: jQuery.validator.format("Будь ласка, введіть значення довжиною від {0} до {1} символів."), + range: jQuery.validator.format("Будь ласка, введіть число від {0} до {1}."), + max: jQuery.validator.format("Будь ласка, введіть число, менше або рівно {0}."), + min: jQuery.validator.format("Будь ласка, введіть число, більше або рівно {0}.") +}); diff --git a/spec/test_app/public/javascripts/nested-attribute.js b/spec/test_app/public/javascripts/nested-attribute.js new file mode 100644 index 0000000..36ceca0 --- /dev/null +++ b/spec/test_app/public/javascripts/nested-attribute.js @@ -0,0 +1,26 @@ +//On page load +// TODO - remove nonconflict stuff once prototype is gone for good +var $j = jQuery.noConflict(); + +replace_ids = function(s){ + var new_id = new Date().getTime(); + return s.replace(/NEW_RECORD/g, new_id); +} + +$j(function() { + $j('a[id*=nested]').click(function() { + var template = $j(this).attr('href').replace(/.*#/, ''); + html = replace_ids(eval(template)); + $j('#ul-' + $j(this).attr('id')).append(html); + update_remove_links(); + }); + update_remove_links(); +}) + +var update_remove_links = function() { + $j('.remove').click(function() { + $j(this).prevAll(':first').val(1); + $j(this).parent().hide(); + return false; + }); +}; diff --git a/spec/test_app/public/javascripts/open_id.js b/spec/test_app/public/javascripts/open_id.js new file mode 100644 index 0000000..0fd5641 --- /dev/null +++ b/spec/test_app/public/javascripts/open_id.js @@ -0,0 +1,15 @@ +$('#enable_login_via_openid a').click(function(){ + $('#enable_login_via_openid').hide(); + $('#enable_login_via_login_password').show(); + $('div#openid-credentials').show(); + $('div#openid-credentials input').removeAttr("disabled"); + $('div#password-credentials').hide(); +}) + +$('#enable_login_via_login_password a').click(function(){ + $('#enable_login_via_openid').show(); + $('#enable_login_via_login_password').hide(); + $('div#openid-credentials').hide(); + $('div#openid-credentials input').attr("disabled", true); + $('div#password-credentials').show(); +}) diff --git a/spec/test_app/public/javascripts/product.js b/spec/test_app/public/javascripts/product.js new file mode 100644 index 0000000..e09a4ac --- /dev/null +++ b/spec/test_app/public/javascripts/product.js @@ -0,0 +1,49 @@ +var add_image_handlers = function() { + $("#main-image").data('selectedThumb', $('#main-image img').attr('src')); + $('ul.thumbnails li').eq(0).addClass('selected'); + $('ul.thumbnails li a').click(function() { + $("#main-image").data('selectedThumb', $(this).attr('href')); + $('ul.thumbnails li').removeClass('selected'); + $(this).parent('li').addClass('selected'); + return false; + }).hover( + function() { + $('#main-image img').attr('src', $(this).attr('href').replace('mini', 'product')); + }, + function() { + $('#main-image img').attr('src', $("#main-image").data('selectedThumb')); + } + ); +}; + +jQuery(document).ready(function() { + add_image_handlers(); +}); + +jQuery(document).ready(function() { + jQuery('#product-variants input[type=radio]').click(function (event) { + var vid = this.value; + var text = $(this).siblings(".variant-description").html(); + + jQuery("#variant-thumbnails").empty(); + jQuery("#variant-images span").html(text); + + if (images[vid].length > 0) { + $.each(images[vid], function(i, link) { + jQuery("#variant-thumbnails").append('
                    • ' + link + '
                    • '); + }); + + jQuery("#variant-images").show(); + } else { + jQuery("#variant-images").hide(); + } + + add_image_handlers(); + + var link = jQuery("#variant-thumbnails a")[0]; + + jQuery("#main-image img").attr({src: jQuery(link).attr('href')}); + jQuery('ul.thumbnails li').removeClass('selected'); + jQuery(link).parent('li').addClass('selected'); + }); +}); diff --git a/spec/test_app/public/javascripts/rails.js b/spec/test_app/public/javascripts/rails.js new file mode 100644 index 0000000..89f219a --- /dev/null +++ b/spec/test_app/public/javascripts/rails.js @@ -0,0 +1,127 @@ +jQuery(function ($) { + var csrf_token = $('meta[name=csrf-token]').attr('content'), + csrf_param = $('meta[name=csrf-param]').attr('content'); + + $.fn.extend({ + /** + * Triggers a custom event on an element and returns the event result + * this is used to get around not being able to ensure callbacks are placed + * at the end of the chain. + * + * TODO: deprecate with jQuery 1.4.2 release, in favor of subscribing to our + * own events and placing ourselves at the end of the chain. + */ + triggerAndReturn: function (name, data) { + var event = new $.Event(name); + this.trigger(event, data); + + return event.result !== false; + }, + + /** + * Handles execution of remote calls firing overridable events along the way + */ + callRemote: function () { + var el = this, + method = el.attr('method') || el.attr('data-method') || 'GET', + url = el.attr('action') || el.attr('href'), + dataType = el.attr('data-type') || 'script'; + + if (url === undefined) { + throw "No URL specified for remote call (action or href must be present)."; + } else { + if (el.triggerAndReturn('ajax:before')) { + var data = el.is('form') ? el.serializeArray() : []; + $.ajax({ + url: url, + data: data, + dataType: dataType, + type: method.toUpperCase(), + beforeSend: function (xhr) { + el.trigger('ajax:loading', xhr); + }, + success: function (data, status, xhr) { + el.trigger('ajax:success', [data, status, xhr]); + }, + complete: function (xhr) { + el.trigger('ajax:complete', xhr); + }, + error: function (xhr, status, error) { + el.trigger('ajax:failure', [xhr, status, error]); + } + }); + } + + el.trigger('ajax:after'); + } + } + }); + + /** + * confirmation handler + */ + $('a[data-confirm],input[data-confirm]').live('click', function () { + var el = $(this); + if (el.triggerAndReturn('confirm')) { + if (!confirm(el.attr('data-confirm'))) { + return false; + } + } + }); + + + /** + * remote handlers + */ + $('form[data-remote]').live('submit', function (e) { + $(this).callRemote(); + e.preventDefault(); + }); + + $('a[data-remote],input[data-remote]').live('click', function (e) { + $(this).callRemote(); + e.preventDefault(); + }); + + $('a[data-method]:not([data-remote])').live('click', function (e){ + var link = $(this), + href = link.attr('href'), + method = link.attr('data-method'), + form = $('
                      '), + metadata_input = ''; + + if (csrf_param != null && csrf_token != null) { + metadata_input += ''; + } + + form.hide() + .append(metadata_input) + .appendTo('body'); + + e.preventDefault(); + form.submit(); + }); + + /** + * disable-with handlers + */ + var disable_with_input_selector = 'input[data-disable-with]'; + var disable_with_form_selector = 'form[data-remote]:has(' + disable_with_input_selector + ')'; + + $(disable_with_form_selector).live('ajax:before', function () { + $(this).find(disable_with_input_selector).each(function () { + var input = $(this); + input.data('enable-with', input.val()) + .attr('value', input.attr('data-disable-with')) + .attr('disabled', 'disabled'); + }); + }); + + $(disable_with_form_selector).live('ajax:complete', function () { + $(this).find(disable_with_input_selector).each(function () { + var input = $(this); + input.removeAttr('disabled') + .val(input.data('enable-with')); + }); + }); +}); diff --git a/spec/test_app/public/javascripts/taxonomy.js b/spec/test_app/public/javascripts/taxonomy.js new file mode 100644 index 0000000..bb9c1b4 --- /dev/null +++ b/spec/test_app/public/javascripts/taxonomy.js @@ -0,0 +1,196 @@ +var base_url = "/admin/taxonomies/" + taxonomy_id + "/taxons/"; +var child_url = "/admin/taxonomies/" + taxonomy_id + "/get_children.json" +var creating = false; +var delete_confirmed = false; +var last_rollback = null; + +var handle_ajax_error = function(XMLHttpRequest, textStatus, errorThrown){ + jQuery.tree.rollback(last_rollback); + + jQuery("#ajax_error").show().html("" + server_error + "
                      " + taxonomy_tree_error); +}; + +var handle_move = function(li, target, droppped, tree, rb) { + last_rollback = rb; + var position = jQuery(li).prevAll().length; + + var parent = -1; + + if(droppped=='inside'){ + parent = target; + }else if(droppped=='after'){ + parent = jQuery(target).parents()[1]; + }else if(droppped=='before'){ + parent = jQuery(target).parents()[1]; + } + + jQuery.ajax({ + type: "POST", + url: base_url + li.id + ".json", + data: ({_method: "put", "taxon[parent_id]": parent.id, "taxon[position]": position, authenticity_token: AUTH_TOKEN}), + error: handle_ajax_error + }); + + return true +}; + +var handle_dblclick = function(li, tree) { + tree.rename(); +}; + +var handle_create = function(parent, sib, created, tree, rb){ + last_rollback = rb; + creating=true; +}; + +var handle_created = function(id,result) { + jQuery.tree.reference('taxonomy_tree').selected.attr('id', id); +} + +var handle_rename = function(li, tree, rb) { + var name = jQuery(li).children(":first").text(); + name = jQuery.trim(name); + + if (creating){ + //actually creating new + var position = jQuery(li).prevAll().length; + var parent = jQuery(li).parents()[1]; + + jQuery.ajax({ + type: "POST", + url: base_url, + data: ({"taxon[name]": name, "taxon[parent_id]": parent.id, "taxon[position]": position, authenticity_token: AUTH_TOKEN}), + error: handle_ajax_error, + success: handle_created + }); + + creating = false; + }else{ + //just renaming + last_rollback = rb; + + jQuery.ajax({ + type: "POST", + url: base_url + li.id + ".json", + data: ({_method: "put", "taxon[name]": name, authenticity_token: AUTH_TOKEN}), + error: handle_ajax_error + }); + } +}; + +var handle_before_delete = function(li){ + if (!delete_confirmed){ + jConfirm('Are you sure you want to delete this taxon?', 'Confirm Taxon Deletion', function(r) { + if(r){ + delete_confirmed = true; + jQuery.tree.reference('taxonomy_tree').remove(li); + } + }); + } + + return delete_confirmed; +}; + +var handle_delete = function(li, tree, rb){ + last_rollback = rb; + + jQuery.ajax({ + type: "POST", + url: base_url + li.id, + data: ({_method: "delete", authenticity_token: AUTH_TOKEN}), + error: handle_ajax_error + }); + + delete_confirmed = false; +}; + +jQuery(document).ready(function(){ + conf = { + data : { + type : "json", + async : true, + opts : { + method : "GET", + url : child_url + } + }, + ui : { + theme_name : "apple" + }, + lang : { + new_node : new_taxon, + loading : loading + "..." + }, + plugins : { + contextmenu : { + items : { + // get rid of the remove item + remove :{ + visible : function (NODE, TREE_OBJ) { if(jQuery(NODE[0]).attr('rel')=="root") return false; return TREE_OBJ.check("renameable", NODE); }, + }, + rename :{ + visible : function (NODE, TREE_OBJ) { if(jQuery(NODE[0]).attr('rel')=="root") return false; return TREE_OBJ.check("renameable", NODE); }, + }, + cut :{ + id : "cut", + label : "Cut", + visible : function (NODE, TREE_OBJ) { if(NODE.length != 1 || NODE[0].id == 'root') return false; return true; }, + action : function (NODE, TREE_OBJ) { TREE_OBJ.cut(NODE); jQuery(NODE).hide(); }, + separator_before : true + }, + paste :{ + id : "paste", + label : "Paste", + visible : function (NODE, TREE_OBJ) { if(NODE.length != 1 || NODE[0].id == 'root') return false; return true; }, + action : function (NODE, TREE_OBJ) { TREE_OBJ.open_branch(NODE); TREE_OBJ.paste(NODE, "inside"); jQuery(NODE).find("li").show(); } + }, + edit :{ + id : "edit", + label : "Edit", + visible : function (NODE, TREE_OBJ) { if(NODE.length != 1 || NODE[0].id == 'root') return false; return TREE_OBJ.check("renameable", NODE); }, + action : function (NODE, TREE_OBJ) { jQuery.each(NODE, function () { window.location = base_url + this.id + "/edit/"; }); } + } + + } + } + }, + rules : { + // only nodes of type root can be top level nodes + valid_children : [ "root" ] + }, + types : { + // all node types inherit the "default" node type + "taxon" : {}, + "root" : { + deletable : false, + renameable : false, + draggable : false, + valid_children : [ "taxon" ] + } + }, + callback : { + onmove: handle_move, + ondblclk: handle_dblclick, + onrename: handle_rename, + oncreate: handle_create, + beforedelete: handle_before_delete, + ondelete: handle_delete, + beforedata: function (n, t) { + if(n == false) t.settings.data.opts.static = initial; + else t.settings.data.opts.static = false; + + return { parent_id : $(n).attr("id") || 0 }; + } + + } + } + + jQuery("#taxonomy_tree").tree(conf); + + jQuery(document).keypress(function(e){ + //surpress form submit on enter/return + if (e.keyCode == 13){ + e.preventDefault(); + } + }); +}); diff --git a/spec/test_app/public/javascripts/zone.js b/spec/test_app/public/javascripts/zone.js new file mode 100644 index 0000000..cd34f7b --- /dev/null +++ b/spec/test_app/public/javascripts/zone.js @@ -0,0 +1,40 @@ +$j(function() { + if ($j('#country_based').attr('checked')) { + show_country(); + } else if ($j('#state_based').attr('checked')) { + show_state(); + } else { + show_zone(); + } + $j('#country_based').click(function() { show_country();} ); + $j('#state_based').click(function() { show_state();} ); + $j('#zone_based').click(function() { show_zone();} ); +}) + +var show_country = function() { + $j('#state_members :input').each(function() { $(this).disable(); }) + $j('#state_members').hide(); + $j('#zone_members :input').each(function() { $(this).disable(); }) + $j('#zone_members').hide(); + $j('#country_members :input').each(function() { $(this).enable(); }) + $j('#country_members').show(); +}; + +var show_state = function() { + $j('#country_members :input').each(function() { $(this).disable(); }) + $j('#country_members').hide(); + $j('#zone_members :input').each(function() { $(this).disable(); }) + $j('#zone_members').hide(); + $j('#state_members :input').each(function() { $(this).enable(); }) + $j('#state_members').show(); +}; + +var show_zone = function() { + $j('#state_members :input').each(function() { $(this).disable(); }) + $j('#state_members').hide(); + $j('#country_members :input').each(function() { $(this).disable(); }) + $j('#country_members').hide(); + $j('#zone_members :input').each(function() { $(this).enable(); }) + $j('#zone_members').show(); +}; + diff --git a/spec/test_app/public/robots.txt b/spec/test_app/public/robots.txt new file mode 100644 index 0000000..085187f --- /dev/null +++ b/spec/test_app/public/robots.txt @@ -0,0 +1,5 @@ +# See http://www.robotstxt.org/wc/norobots.html for documentation on how to use the robots.txt file +# +# To ban all spiders from the entire site uncomment the next two lines: +# User-Agent: * +# Disallow: / diff --git a/spec/test_app/public/stylesheets/admin/admin-forms.css b/spec/test_app/public/stylesheets/admin/admin-forms.css new file mode 100755 index 0000000..15019ff --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/admin-forms.css @@ -0,0 +1,159 @@ +/* -------------------------------------------------------------- + + forms.css + * Sets up some default styling for forms + * Gives you classes to enhance your forms + + Usage: + * For text fields, use class .title or .text + +-------------------------------------------------------------- */ + +label { font-weight: bold; } +fieldset { padding:1.4em; margin: 0 0 1.5em 0; border: 1px solid #ccc; } +legend { font-weight: bold; font-size:1.2em; margin:0; } + + +/* Form fields +-------------------------------------------------------------- */ + +input.text, input.title, +input, textarea, select { + margin:0.25em 0; + border:1px solid #bbb; +} + +input.text:focus, input.title:focus, +textarea:focus, select:focus { + border:1px solid #666; +} + +input.text, +input.title { padding:5px; } +input.title { font-size:1.5em; } +textarea { height: 250px; padding:5px; } + +.required { color:#f00; font-weight:bold; font-size:1.2em;} +.fullwidth { width:98% } + +/* container that holds a field that's got a master label then labels under each sub field e.g. Name might have firstname, lastname */ +.sub-field { margin:0; padding:0; margin:0 0 0.25em 0 } +.sub-field label, label.sub { font-weight:normal; color:#333; } +.sub-field input { margin-bottom:0 } + + +.date-range-filter {width:220px;} + .date-range-filter input {width:75px;} + .date-range-filter .yui-u { width:50% } + + +/* Multi-column form layout +-------------------------------------------------------------- */ +div.split { + background-color:#eee; +} +form div.left +{ + display:inline; + float:left; + width:48%; +} + +form div.right +{ + display:inline; + float:right; + width:48%; +} +form p { + clear:both; +} +form div.left.w70 { + width:68%; +} +form div.right.w30 { + width:28%; +} + + +/* Flashes and error messages +-------------------------------------------------------------- */ + +.flash { + font-size:130%;font-weight:bold; + padding: .4em 0 .4em 38px; margin-bottom: 1em; + border:1px solid #c00; + border-left:none;border-right:none; +} +.flash.error { + background: #FDE4E4 url(../../images/admin/icons/exclamation.png) 10px center no-repeat; + color:#c00; border-color:#c00; +} +.flash.notice { + background: #E7F8D7 url(../../images/admin/icons/tick.png) 10px center no-repeat; + color:#59A151; border-color: #59A151; +} + +.withError { + background-color:#FDE4E4; + background-image:url(../../images/admin/bg/red-stripes.png); +} +.formError { + color:#c00; font-weight:bold; + display:block; +} + + +.member-list { + list-style:none;margin:0; +} + + +.form-buttons { + margin-top: 1em; + clear: both; + } + .form-buttons a { + text-transform: lowercase; } + +.field { + margin-bottom: 1em; + clear: both; + position: relative; } + .field .formError { + color: #fff; + background: #f15700 url(../../images/admin/icons/fugue/exclamation_small.png) center left no-repeat; + padding: 3px 7px; + display: inline-block; + margin-bottom: 1em; + padding-left: 20px; } + .field.fluid { + clear: none; + float: left; + margin-right: 1em; } + .field label { + display: block; } + .field label span.label { + display: block; } + + + + + + +fieldset { + margin-bottom: 1em; + padding: 1em; + border: solid 1px #ccc; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; + } + fieldset h1 { + font-size: 1.75em; } + fieldset table.index th:first-child { + -moz-border-radius-topleft: 5px; + -webkit-border-top-left-radius: 5px; } + fieldset table.index th:last-child { + -moz-border-radius-topright: 5px; + -webkit-border-top-right-radius: 5px; } + diff --git a/spec/test_app/public/stylesheets/admin/admin-reset.css b/spec/test_app/public/stylesheets/admin/admin-reset.css new file mode 100644 index 0000000..70b7d48 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/admin-reset.css @@ -0,0 +1,67 @@ +html, body { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; } + +div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, +pre, a, abbr, acronym, address, code, del, dfn, em, img, +dl, dt, dd, ol, ul, li, fieldset, form, label, legend, caption, tbody, tfoot, thead, tr, hr { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; } + +body { line-height: 1.5 } + +blockquote, q { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; + quotes: "" ""; } + blockquote:before, + blockquote:after, q:before, + q:after { + content: ""; } + +th, td, caption { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; + text-align: left; + font-weight: normal; + vertical-align: top; } + +table { + margin: 0; + padding: 0; + border: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; + border-collapse: separate; + border-spacing: 0; + vertical-align: middle; } + +a img { border: none } + diff --git a/spec/test_app/public/stylesheets/admin/admin-tables.css b/spec/test_app/public/stylesheets/admin/admin-tables.css new file mode 100644 index 0000000..8a5829d --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/admin-tables.css @@ -0,0 +1,39 @@ +table.index th { + background: #cdcdcd url(../../images/admin/bg/grid_header_back.png) top left repeat-x; + padding: 7px 10px; + border-left: 1px solid #ddd; + border-top: 1px solid #ddd; + border-right: 1px solid #aaa; + border-bottom: 1px solid #aaa; + text-shadow: #efefef 1px 1px 0px; } + table.index th .right { + float:right; + font-weight:normal; + } + table.index th.id-col { + text-align: center; } + table.index td { + border-bottom:1px solid #ddd; + padding: 3px 10px; + } + table.index td.lbl-col { + width: 12%; } + table.index td.val-col { + width: 38%; } +table.index tr.alt td { + background-color: #efefef; } +table.index.green th { + background: #cfefa7 url(/images/grid_header_back_green.png) top left repeat-x; + border-left: 1px solid #E4FDB4; + border-top: 1px solid #E4FDB4; + border-right: 1px solid #B7CB90; + border-bottom: 1px solid #B7CB90; } +table.index.green td { + background-color: #efe; } +table.index.order-summary { + clear: both; } + table.index.order-summary tr.totals th { + background: transparent; + text-align: right; + border: none; } +table.index td.actions {text-align:right;} diff --git a/spec/test_app/public/stylesheets/admin/admin-typography.css b/spec/test_app/public/stylesheets/admin/admin-typography.css new file mode 100755 index 0000000..345fe84 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/admin-typography.css @@ -0,0 +1,117 @@ +/* -------------------------------------------------------------- + + typography.css + * Sets up some sensible default typography. + +-------------------------------------------------------------- */ + +/* Default font settings. + The font-size percentage is of 16px. (0.75 * 16px = 12px) */ +body { + font-size: 75%; + color: #222; + font-family: "Helvetica Neue", Helvetica, Tahoma, Verdana, Arial, sans-serif; +} + +/* Headings +-------------------------------------------------------------- */ + +h1,h2,h3,h4,h5,h6 { font-weight: bold; color: #111; } + +h1 { font-size: 2.5em; margin-bottom: 0.75em; line-height: 1em; } +h2 { font-size: 1.5em; line-height: 1; margin-bottom: 0.6em; } +h3 { font-size: 1.5em; line-height: 1.25; margin-bottom: 0.6em; } +h4 { font-size: 1em; font-weight: bold; margin-bottom: 1.5em; } +h5 { font-size: 1em; font-weight: bold; } +h6 { font-weight: normal } + +h1 img, h2 img, h3 img, +h4 img, h5 img, h6 img { margin: 0 } + + +h1, h2 { letter-spacing: -1px } + + +/* Text elements +-------------------------------------------------------------- */ + +p { margin: 0 0 1em; } +p img.left { float: left; margin: 1.5em 1.5em 1.5em 0; padding: 0; } +p img.right { float: right; margin: 1.5em 0 1.5em 1.5em; } + +a:focus, +a:hover { color: #000; } +a { color: #009; text-decoration: none; } + +blockquote { margin: 1.5em; color: #666; font-style: italic; } +strong { font-weight: bold; } +em,dfn { font-style: italic; } +dfn { font-weight: bold; } +sup, sub { line-height: 0; } + +abbr, +acronym { border-bottom: 1px dotted #666; } +address { margin: 0 0 1.5em; font-style: italic; } +del { color:#666; } + +pre { margin: 1.5em 0; white-space: pre; } +pre,code,tt { font: 1em 'andale mono', 'lucida console', monospace; line-height: 1.5; } + + +/* Lists +-------------------------------------------------------------- */ + +li ul, +li ol { margin:0 1.5em; } +ul, ol { margin: 0 1.5em 1.5em 1.5em; } + +ul { list-style-type: disc; } +ol { list-style-type: decimal; } + +dl { margin: 0 0 1.5em 0; } +dl dt { font-weight: bold; } +dd { margin-left: 1.5em;} + + +/* Tables +-------------------------------------------------------------- */ + +table { margin-bottom: 1.4em; width:100%; } +th { font-weight: bold; } +thead th { background: #c3d9ff; } +th,td,caption { padding: 4px 10px 4px 5px; } +tr.even td { background: #e5ecf9; } +tfoot { font-style: italic; } +caption { background: #eee; } + + +/* Misc +-------------------------------------------------------------- */ + +hr { clear: both; height:0; border:none} + +.small { font-size: .8em; margin-bottom: 1.875em; line-height: 1.875em; } +.large { font-size: 1.2em; line-height: 2.5em; margin-bottom: 1.25em; } +.hide { display: none; } + +.quiet { color: #666; } +.loud { color: #000; } +.highlight { background:#ff0; } +.added { background:#060; color: #fff; } +.removed { background:#900; color: #fff; } + +.first { margin-left:0; padding-left:0; } +.last { margin-right:0; padding-right:0; } +.top { margin-top:0; padding-top:0; } +.bottom { margin-bottom:0; padding-bottom:0; } + + +.clear { clear: both } +.nowrap { white-space: nowrap } + +.clearfix { + overflow: auto; + overflow: -moz-scrollbars-none; + display: inline-block; } + .clearfix { + display: block; } diff --git a/spec/test_app/public/stylesheets/admin/admin.css b/spec/test_app/public/stylesheets/admin/admin.css new file mode 100644 index 0000000..216d1e5 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/admin.css @@ -0,0 +1,579 @@ +#language-bar, +#login-nav, +#store-nav { + float: right; + margin-top: 10px;} + #language-bar li, + #login-nav li, + #store-nav li { + float: left; + margin-right: 1em; + list-style: none; } + +.address-form label, +#creditcard label { + width: 200px; + display: block; + float: left; } + +#creditcard label { + width: 150px; } + +input.default { + color: #999; } + input.default:focus { + color: inherit; } + +p.help-text { + font-style: italic; + font-weight: normal; + margin-bottom: 0; + color: #999; } + + + + +body { + margin-top: 0px; + background-color: #162F54; + color: #476D9B; + } + + a { + color: #4884BD; } + a:active, + a:visited { + color: #4884BD; } + + #header { + height:95px; + position: relative; + margin-bottom: 13px; + } + #header, + #footer { + position: relative; + clear: both; } + #content { + margin: 0em 1em 1em 1em; + padding: 1em; + background: #fff; + color: #111; + min-height: 500px; } + #content a { + color: #3C7DFB; } + #content a:active, + #content a:visited { + color: #3C7DFB; } + #content.with-sidebar { + background: #fff url(../../images/admin/bg/content-back.png) right top repeat-y; + padding-right: 340px; + position: relative; } + #sidebar { + position: absolute; + width: 305px; + top: 0; right: 0; + padding-top: 3em; + } + #sidebar .box { + padding:10px; + } + #sidebar .box h3 { margin: 0 0 10px 0; } + #sidebar h3 { + margin: 0 10px; } + #sidebar h3 a { + color: #111; + text-decoration: none; } + #sidebar h5 { + margin: 0 10px; + width: 130px; + float: left;} + #sidebar span.sku { + display: block; + font-weight: normal; } + #sidebar img { + float: right; + margin-right: 1em; } + #sidebar img.calendar_date_select_popup_icon { + float: none; } + #sidebar .field { + padding: 0 1em; } + #sidebar .form-buttons { + padding: 0 1em; } + #sidebar h4 { + margin-left: 10px; } + #sidebar ul.sidebar { + clear: both; + position: relative; + margin: 0; + padding: 0; } + #sidebar ul.sidebar li { + list-style: none; } + #sidebar ul.sidebar li a { + display: block; + padding: 10px 20px 10px; + outline: none; + text-decoration: none; + color: #666 !important; } + #sidebar ul.sidebar li a:hover { background-color:#ddd } + #sidebar ul.sidebar li.active a { + font-weight: bold; + background: url(../../images/admin/bg/menu-current.png) left center no-repeat; + color: #363 !important; + margin-left: -20px; + padding-left: 30px; } + #sidebar .order-number, + #sidebar .order-status { + text-align: right; + margin-right: 20px; } + #sidebar .order-status { + padding: 7px 15px; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + float: right; + background-color: #999; + color: #111; + text-transform: uppercase; } + #sidebar .order-status.new { + background-color: #5D9C0F; + color: #fff; } + #sidebar .order-status.canceled { + background-color: #c00; + color: #fff; } + + #header #logo { + position: absolute; + top: 0; + left: 10px; +} + #header h1 { + position: absolute; + left: 200px; + bottom: 19px; + margin: 10px 10px 10px 10px; + display: block; + text-decoration: none; + line-height: 100%; + + } + #header h1 a { + color: #8CB952; + } + #admin-menu { clear: both; } + #admin-menu, + #sub-menu { + margin: 0 1em; + } + #admin-menu li { + + } + #admin-menu ul, + #sub-menu ul { + padding: 0; + margin: 0; } + #admin-menu ul li, + #sub-menu ul li { + float: left; + margin-right: 1em; + list-style: none; } + #admin-menu ul li, + #sub-menu ul li { + margin-right: 0; margin-bottom: -1px;} + #admin-menu ul li a, + #sub-menu ul li a { + display: block; + padding: 10px 20px; + color: #fff; + text-decoration: none; + outline: none; } + #admin-menu ul li.selected a, + #sub-menu ul li.selected a { + background-color: #0095da; + } + #admin-menu ul li.selected { + border-bottom:1px solid #0095DA; + } + #IE7 #admin-menu { + height: 39px; } + #admin-menu { + background: #154e8c url(../../images/admin/bg/admin_tab_back.png) top left repeat-x; + border-top: 1px solid #4B83E2; + border-right: 1px solid #34599B; + border-bottom: 1px solid #41A6F0; + } + #admin-menu ul { + margin-bottom: -1px; } + #admin-menu ul li:first-child { + border-left: 1px solid #34599B; } + #admin-menu ul li.selected { + background: #0095da url(../../images/admin/bg/admin_tab_selected_back.png) top left repeat-x; + border-left: 1px solid #41A6F0; + border-top: 1px solid #41A6F0; + border-right: 1px solid #4986BF; + height: 40px; + margin-top: -2px; } + #sub-menu { + background: #0095da; + border-left: 1px solid #41A6F0; + border-right: 1px solid #4986BF; } + #IE7 #sub-menu ul { + height: 26px; } + #sub-menu ul li a { + padding: 3px 7px; + margin: 10px 5px; + color: #154e8c; + background: none; } + #sub-menu ul li.selected a { + background: #154e8c; + color: #9BC3FC; + -moz-border-radius: 3px; + -webkit-border-radius: 3px; } + #slide-content { + margin: 0 1em; + background-color: #cdf; } + .toolbar { + float: right; + margin-bottom: 1em; } + .toolbar ul.actions { + margin: 0; + padding: 0; + float: right; } + .toolbar ul.actions li { + float: left; + margin-right: 1em; + list-style: none; } + .toolbar ul.actions li { + margin-right: 0; } + .toolbar.order-links a { + text-transform: capitalize; } + .search-form { + display: none; + padding: 1em; } + .search-form label { + display: block; } + a.button { + background: transparent url(../../images/admin/buttons/right_01.png) no-repeat scroll top right; + display: block; + float: left; + margin-right: 6px; + padding-right: 20px; + text-decoration: none; + color: #111 !important; + font-weight: bold; + outline: none; } + a.button span { + background: transparent url(../../images/admin/buttons/left_01.png) no-repeat; + display: block; + line-height: 22px; + padding: 7px 0 5px 14px; + text-shadow: #efefef 1px 1px 0px; } + a.button img { + vertical-align: middle; + margin: 0 3px 0 0; } + a.button.cancel span { + font-weight: normal; } + a.button.small { + font-size: 1em; + background: transparent url(../../images/admin/buttons/right_01_small.png) no-repeat scroll top right; + padding-right: 20px; } + a.button.small span { + background: transparent url(../../images/admin/buttons/left_01_small.png) no-repeat; + padding: 5px 0 3px 20px; + line-height: 21px; } + a.button.green { + background: transparent url(../../images/admin/buttons/green/right_01.png) no-repeat scroll top right; + color: #151 !important; } + a.button.green span { + background: transparent url(../../images/admin/buttons/green/left_01.png) no-repeat; } + button { + border: 0; + cursor: pointer; + font-weight: bold; + padding: 0 20px 0 0; + text-align: center; + background: url(../../images/admin/buttons/right_01.png) center right no-repeat; + font-size: 1.3em; + outline: none; } + button span { + position: relative; + display: block; + white-space: nowrap; + padding: 0 0 0 20px; + height: 35px; + line-height: 35px; + background: url(../../images/admin/buttons/left_01.png) center left no-repeat; + text-shadow: #efefef 1px 1px 0px; } + button span img { + vertical-align: middle; + margin: 0 3px 0 0; } + button:focus { + outline: none; } + button.tick { + background: none; + width: 24px; } + input.title, + textarea { + margin: 0; } + .errorExplanation { + border: solid 2px #f15700; + padding: 1em; + margin-bottom: 1em; + background: #cdf; + -moz-border-radius: 10px; + -webkit-border-radius: 10px; } + .errorExplanation ul { + color: #f15700; + list-style: square; } + .errorExplanation h2 { + font-size: 1.75em; + padding-left: 40px; + background: url(../../images/admin/icons/orb/32x32/3.png) center left no-repeat; } + ul.checkbox-list { + list-style: none; } + ul.checkbox-list li { + display: block; + float: left; + width: 200px; } + ul.checkbox-list li label { + font-weight: normal !important; } + #busy_indicator { + margin-bottom: 1em; } + select#filter_state { + font-size: 1.5em; } + h2.order-number { + margin-bottom: 0; } + h4.order-status { + display: block; + font-weight: normal; } + .adr { + float: left; + margin-right: 1em; + margin-bottom: 1em; + padding: 1em; + border: solid 1px #999; + -moz-border-radius: .5em; + -webkit-border-radius: .5em; + min-width: 46%; } + .adr .fn { + font-weight: bold; } + .adr h4 { + margin-bottom: 1em; + border-bottom: 1px solid #ccc; + padding-bottom: .5em; + color: #666; } + ul.taxonomy-tree { + cursor: default; + list-style: none; + margin: 0; + padding: 0 0 0 35px; + min-height: 2em; } + ul.taxonomy-tree li.taxon { + clear: both; + padding: 5px; } + ul.taxonomy-tree li.taxon span, + ul.taxonomy-tree li.taxon input { + float: left; + margin-right: 1em; } + ul.taxonomy-tree li.taxon .name { + float: left; + cursor: move; } + ul.taxonomy-tree li.taxon.new ul.taxonomy-actions, + ul.taxonomy-tree li.taxon.editing ul.taxonomy-actions { + display: none; } + ul.taxonomy-tree li.taxon.to-destroy { + color: #900; + text-decoration: line-through; } + ul.taxonomy-tree li.taxon.to-destroy ul.taxonomy-actions { + display: none; } + .placeholder { + height: 30px; + clear: both; + border: dashed 2px #ddd; } + ul.taxonomy-actions { + float: left; + list-style: none; + margin: 0px 0px 10px 10px; + padding: 0; } + ul.taxonomy-actions li { + float: left; + margin-right: 5px; } + ul.taxonomy-actions li img { + vertical-align: text-top; } + ul.taxonomy-actions li.disabled { + opacity: .5; } + h3.warning { + background-image: url(../../images/admin/icons/fugue/exclamation.png); + background-position: 10px 15px; + background-repeat: no-repeat; + padding-left: 35px; } + #searching { + clear: both; + margin-top: 2em; } + + +.pagination{ + padding-top: 10px; + text-align: right; +} +a.page, span.page { + padding: 0px 5px; + margin: 0 3px; +} +a.page { + text-decoration: none; + border: 1px solid #9aafe5; + color: #2e6ab1; +} +a.page:hover, a.page:active { + border: 1px solid #2b66a5; + color: #000; + background-color: LightYellow; +} + +a.next_page { + font-weight: bold; +} + + +span.disabled_page { + border: 1px solid #929292; + color: #929292; +} + +span.current_page { + font-weight: bold; + border: 1px solid navy; + background-color: #2e6ab1; + color: #FFF; +} + +div#calculator-settings-warning { + color: #f00; +} +#progress{ + display:none; + background:#154E8C url(../../images/admin/bg/admin_tab_back.png) repeat-x scroll left top; + color:#fff; + font-size:170%; + height:25px; + left:33%; + padding:10px 0 15px; + position:fixed; + text-align:center; + width:320px; + font-weight:bold; + -moz-border-radius-bottomleft:15px; + -moz-border-radius-bottomright:15px; + -webkit-border-bottom-left-radius: 15px; + -webkit-border-bottom-right-radius: 15px; +} +#progress img{ + vertical-align:middle; + padding-right:10px; +} + +ul#shipping-specs { + margin: 0; + padding-bottom:10px; +} +ul#shipping-specs li { + list-style-image:none; + display:inline; +} + +.product-scopes ul > li { + float: left; + width: 220px; + margin-right: 20px; +} + +.product-scopes .invalid { + background-color: red; +} + +div.product-preview-products { + max-height: 200px; + overflow: auto; +} + +#preference-settings input, #preference-settings select, #preference-settings textarea{ + float:left; + +} + +#preference-settings input[type=text], #preference-settings input[type=password] { + width: 250px; +} + +#preference-settings input.input_integer[type=text] { + width: 100px; +} + +#preference-settings label{ + clear:both; + display:block; + float:left; + width:170px; +} +.index .price{ + width: 50px; + text-align:center; +} +.index .qty{ + width: 50px; + text-align:center; +} +.index .total{ + width: 50px; + text-align:right; +} +.index .orders-actions{ + width:40px; + padding-left:10px; +} + + + + + + + +/* Product Groups */ + +table#product_scopes tr { + background-color: #eee; + +} +table#product_scopes tr td { + border-top: 4px solid #fff; + border-bottom: 1px solid #bbb; + padding: 5px 10px; +} +table#product_scopes tr td.actions { + vertical-align: middle; + text-align: right; +} +table#product_scopes tr td table { + margin: 0; + width: auto; +} +table#product_scopes tr td table tr td { + padding: 0; + border: none; + padding-right: 5px; +} + +#product_group_forms_container { + position: relative; +} +#new_product_group_form { + position: absolute; + right: 25px; + bottom: 0; +} +#new_product_group_form p { + text-align: right; + margin: 0; +} + + diff --git a/spec/test_app/public/stylesheets/admin/autocomplete.css b/spec/test_app/public/stylesheets/admin/autocomplete.css new file mode 100644 index 0000000..7c5fe77 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/autocomplete.css @@ -0,0 +1,73 @@ +/* @override http://localhost:3000/stylesheets/admin/edit_orders.css */ + +.ac_results { + padding: 0px; + border: 1px solid #666; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding: 5px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; + border-bottom: 1px solid #666; + color: #000; + cursor: pointer; +} + +.ac_results li img{ + float:left; + padding-right: 5px; + width: 30px; +} +.ac_results li h4 { + margin-bottom: 3px; + width: 330px; + white-space: nowrap; + overflow: hidden; +} +.ac_results li div{ + float:left; +} +.ac_results li span{ + display: block; + float: left; +} +.ac_loading { + background: none; +} +.ac_odd { + background-color: #fff; +} +.ac_over { + background-color: #41A6F0; + color: #fff!important; +} +.ac_over h4 { + color: #fff; +} + diff --git a/spec/test_app/public/stylesheets/admin/dashboard.css b/spec/test_app/public/stylesheets/admin/dashboard.css new file mode 100644 index 0000000..ac79c51 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/dashboard.css @@ -0,0 +1,143 @@ +.dashboard h2{ + padding-bottom:5px; + color: #476D9B; + clear:both; +} + +.dashboard_left{ + width:25%; + float:left; +} + +.dashboard_main{ + width:55%; + float:left; +} + +.dashboard_main #orders_by_day_options{ + background-color:#0095DA; + -moz-border-radius-bottomleft:10px; + -moz-border-radius-bottomright:10px; + -moz-border-radius-topleft:10px; + -moz-border-radius-topright:10px; + -webkit-border-bottom-left-radius: 10px 10px; + -webkit-border-bottom-right-radius: 10px 10px; + -webkit-border-top-left-radius: 10px 10px; + -webkit-border-top-right-radius: 10px 10px; + color:#fff; + margin-top:10px; + padding:5px; + text-align:center; +} + +#order_by_day_title{ + padding-bottom:5px; + color: #476D9B; + clear:both; +} + +#order_totals{ + background:#154E8C url(../../images/admin/bg/admin_tab_back.png) repeat-x scroll left top; + -moz-border-radius-bottomleft:10px; + -moz-border-radius-bottomright:10px; + -moz-border-radius-topleft:10px; + -moz-border-radius-topright:10px; + -webkit-border-bottom-left-radius: 10px 10px; + -webkit-border-bottom-right-radius: 10px 10px; + -webkit-border-top-left-radius: 10px 10px; + -webkit-border-top-right-radius: 10px 10px; + color:#fff; + height:62px; + padding:0 10px; + margin-bottom:20px; +} + +#order_totals hr{ + background-color:#fff; + clear:none; + float:left; + height:80%; + margin-top:6px; + width:3px; +} + +#order_totals .spacer{ + padding: 0px 10px; + font-size: 50px; + line-height: 60px; + color: #476D9B; +} + +#order_totals p{ + float:left; + font-size:420%; + font-weight:bold; + line-height:60px; + margin:0 5px 0 0; +} + +#order_totals label{ + font-size:200%; + line-height:50px; +} + +#order_totals span{ + display:block; + font-size:90%; + font-weight:bold; + margin-top: -10px; +} + +.dashboard_main #orders_by_day_options label{ + padding: 0px 10px; +} + +.dashboard_right{ + width:20%; + float:left; +} + +.dashboard table th{ + background-color: #0095DA; + color: #fff; +} + +.dashboard_small_wrapper{ + padding: 0px 20px 0px 0px; +} + +.dashboard_main_wrapper{ + padding: 0px 30px 10px 30px; + margin-left: auto; + margin-right: auto; +} + +#pie_legend{ + width:50%; + float:left; + font-size: 80%; +} + +#pie_legend span{ + line-height:15px; + width:15px; + float:left; +} + +#pie_legend label{ + margin-left:5px; + float:left; +} + +#pie_legend div{ + clear:both; + text-align:right; +} + +.text-right{ + text-align:right; +} + +.jqplot-table-legend{ + width:60px; +} \ No newline at end of file diff --git a/spec/test_app/public/stylesheets/admin/edit_checkouts.css b/spec/test_app/public/stylesheets/admin/edit_checkouts.css new file mode 100644 index 0000000..e182102 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/edit_checkouts.css @@ -0,0 +1,57 @@ +.ac_results { + padding: 0px; + border: 1px solid black; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding: 5px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; + border-bottom: 1px solid black; + color: #000; + cursor: pointer; +} + +.ac_results li h4 { + margin-bottom: 3px; +} +.ac_results li span{ + display: block; +} +.ac_loading { + background: none; +} +.ac_odd { + background-color: #fff; +} +.ac_over { + background-color: #fff; +} +.ac_over h4{ + text-decoration: underline; +} \ No newline at end of file diff --git a/spec/test_app/public/stylesheets/admin/grids.css b/spec/test_app/public/stylesheets/admin/grids.css new file mode 100644 index 0000000..a1b19d2 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/grids.css @@ -0,0 +1,314 @@ +/* +Copyright (c) 2009, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.7.0 +*/ +/** + * YUI Grids + * @module grids + * @namespace yui- + * @requires reset, fonts + */ + +/** + * Note: Throughout this file, the *property (star-property) filter is used + * to give a value to IE that other browsers do not see. _property is only seen + * by IE7, so the combo of *prop and _prop can target between IE6 and IE7. + * + * More information on these filters and related validation errors: + * http://tech.groups.yahoo.com/group/ydn-javascript/message/40059 + */ + +/** + * Section: General Rules + */ + +/** + * Section: Page Width Rules (#doc, #doc2, #doc3, #doc4) + */ + +.yui-g .yui-u .yui-g { + width: 100%; +} + +/** + * Section: Grids and Nesting Grids + */ + +/* Children generally take half the available space */ +.yui-gb .yui-u, +.yui-g .yui-gb .yui-u, +.yui-gb .yui-g, +.yui-gb .yui-gb, +.yui-gb .yui-gc, +.yui-gb .yui-gd, +.yui-gb .yui-ge, +.yui-gb .yui-gf, +.yui-gc .yui-u, +.yui-gc .yui-g, +.yui-gd .yui-u { + float: left; +} + +/* Float units (and sub grids) to the right */ +.yui-g .yui-u, +.yui-g .yui-g, +.yui-g .yui-gb, +.yui-g .yui-gc, +.yui-g .yui-gd, +.yui-g .yui-ge, +.yui-g .yui-gf, +.yui-gc .yui-u, +.yui-gd .yui-g, +.yui-g .yui-gc .yui-u, +.yui-ge .yui-u, +.yui-ge .yui-g, +.yui-gf .yui-g, +.yui-gf .yui-u { + float: right; +} + +/*Float units (and sub grids) to the left */ +.yui-g div.first, +.yui-gb div.first, +.yui-gc div.first, +.yui-gd div.first, +.yui-ge div.first, +.yui-gf div.first, +.yui-g .yui-gc div.first, +.yui-g .yui-ge div.first, +.yui-gc div.first div.first { + float: left; +} + +.yui-g .yui-u, +.yui-g .yui-g, +.yui-g .yui-gb, +.yui-g .yui-gc, +.yui-g .yui-gd, +.yui-g .yui-ge, +.yui-g .yui-gf { + width: 49.1%; +} + +.yui-gb .yui-u, +.yui-g .yui-gb .yui-u, +.yui-gb .yui-g, +.yui-gb .yui-gb, +.yui-gb .yui-gc, +.yui-gb .yui-gd, +.yui-gb .yui-ge, +.yui-gb .yui-gf, +.yui-gc .yui-u, +.yui-gc .yui-g, +.yui-gd .yui-u { + width: 32%; + margin-left: 1.99%; +} + +/* Give IE some extra breathing room for 1/3-based rounding issues */ +.yui-gb .yui-u { + *margin-left: 1.9%; + *width: 31.9%; +} + +.yui-gc div.first, + .yui-gd .yui-u { + width: 66%; +} + +.yui-gd div.first { + width: 32%; +} + +.yui-ge div.first, + .yui-gf .yui-u { + width: 74.2%; +} + +.yui-ge .yui-u, + .yui-gf div.first { + width: 24%; +} + +.yui-g .yui-gb div.first, +.yui-gb div.first, +.yui-gc div.first, +.yui-gd div.first { + margin-left: 0; +} + +/** + * Section: Deep Nesting + */ + +.yui-g .yui-g .yui-u, +.yui-gb .yui-g .yui-u, +.yui-gc .yui-g .yui-u, +.yui-gd .yui-g .yui-u, +.yui-ge .yui-g .yui-u, +.yui-gf .yui-g .yui-u { + width: 49%; + *width: 48.1%; + *margin-left: 0; +} + +.yui-g .yui-g .yui-u { + width: 48.1%; +} + +/*SF 1927599 from 1.14 to 2.6.0*/ +.yui-g .yui-gb div.first, + .yui-gb .yui-gb div.first { + *margin-right: 0; + *width: 32%; + _width: 31.7%; +} + +.yui-g .yui-gc div.first, + .yui-gd .yui-g { + width: 66%; +} + +.yui-gb .yui-g div.first { + *margin-right: 4%; + _margin-right: 1.3%; +} + +.yui-gb .yui-gc div.first, + .yui-gb .yui-gd div.first { + *margin-right: 0; +} + +.yui-gb .yui-gb .yui-u, + .yui-gb .yui-gc .yui-u { + *margin-left: 1.8%; + _margin-left: 4%; +} + +.yui-g .yui-gb .yui-u { + _margin-left: 1.0%; +} + +.yui-gb .yui-gd .yui-u { + *width: 66%; + _width: 61.2%; +} + +.yui-gb .yui-gd div.first { + *width: 31%; + _width: 29.5%; +} + +.yui-g .yui-gc .yui-u, + .yui-gb .yui-gc .yui-u { + width: 32%; + _float: right; + margin-right: 0; + _margin-left: 0; +} + +.yui-gb .yui-gc div.first { + width: 66%; + *float: left; + *margin-left: 0; +} + +.yui-gb .yui-ge .yui-u, + .yui-gb .yui-gf .yui-u { + margin: 0; +} + +.yui-gb .yui-gb .yui-u { + _margin-left: .7%; +} + +.yui-gb .yui-g div.first, + .yui-gb .yui-gb div.first { + *margin-left: 0; +} + +.yui-gc .yui-g .yui-u, + .yui-gd .yui-g .yui-u { + *width: 48.1%; + *margin-left: 0; +} + +.yui-gb .yui-gd div.first { + width: 32%; +} + +.yui-g .yui-gd div.first { + _width: 29.9%; +} + +.yui-ge .yui-g { + width: 24%; +} + +.yui-gf .yui-g { + width: 74.2%; +} + +.yui-gb .yui-ge div.yui-u, + .yui-gb .yui-gf div.yui-u { + float: right; +} + +.yui-gb .yui-ge div.first, + .yui-gb .yui-gf div.first { + float: left; +} + +/* Width Accommodation for Nested Contexts */ +.yui-gb .yui-ge .yui-u, + .yui-gb .yui-gf div.first { + *width: 24%; + _width: 20%; +} + +/* Width Accommodation for Nested Contexts */ +.yui-gb .yui-ge div.first, + .yui-gb .yui-gf .yui-u { + *width: 73.5%; + _width: 65.5%; +} + +/* Patch for GD within GE */ +.yui-ge div.first .yui-gd .yui-u { + width: 65%; +} + +.yui-ge div.first .yui-gd div.first { + width: 32%; +} + +/* @group Clearing */ +#hd:after, +#bd:after, +#ft:after, +.yui-g:after, +.yui-gb:after, +.yui-gc:after, +.yui-gd:after, +.yui-ge:after, +.yui-gf:after { + content: "."; + display: block; + height: 0; + clear: both; + visibility: hidden; +} + +#hd, +#bd, +#ft, +.yui-g, +.yui-gb, +.yui-gc, +.yui-gd, +.yui-ge, +.yui-gf { + zoom: 1; +} diff --git a/spec/test_app/public/stylesheets/admin/reset-fonts-grids-2-6-0.css b/spec/test_app/public/stylesheets/admin/reset-fonts-grids-2-6-0.css new file mode 100644 index 0000000..b3e042c --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/reset-fonts-grids-2-6-0.css @@ -0,0 +1,7 @@ +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.6.0 +*/ +html{color:#000;background:#FFF;}body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,textarea,p,blockquote,th,td{margin:0;padding:0;}table{border-collapse:collapse;border-spacing:0;}fieldset,img{border:0;}address,caption,cite,code,dfn,em,strong,th,var{font-style:normal;font-weight:normal;}li{list-style:none;}caption,th{text-align:left;}h1,h2,h3,h4,h5,h6{font-size:100%;font-weight:normal;}q:before,q:after{content:'';}abbr,acronym{border:0;font-variant:normal;}sup{vertical-align:text-top;}sub{vertical-align:text-bottom;}input,textarea,select{font-family:inherit;font-size:inherit;font-weight:inherit;}input,textarea,select{*font-size:100%;}legend{color:#000;}del,ins{text-decoration:none;}body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}select,input,button,textarea{font:99% arial,helvetica,clean,sans-serif;}table{font-size:inherit;font:100%;}pre,code,kbd,samp,tt{font-family:monospace;*font-size:108%;line-height:100%;}body{text-align:center;}#ft{clear:both;}#doc,#doc2,#doc3,#doc4,.yui-t1,.yui-t2,.yui-t3,.yui-t4,.yui-t5,.yui-t6,.yui-t7{margin:auto;text-align:left;width:57.69em;*width:56.25em;min-width:750px;}#doc2{width:73.076em;*width:71.25em;}#doc3{margin:auto 10px;width:auto;}#doc4{width:74.923em;*width:73.05em;}.yui-b{position:relative;}.yui-b{_position:static;}#yui-main .yui-b{position:static;}#yui-main,.yui-g .yui-u .yui-g{width:100%;}{width:100%;}.yui-t1 #yui-main,.yui-t2 #yui-main,.yui-t3 #yui-main{float:right;margin-left:-25em;}.yui-t4 #yui-main,.yui-t5 #yui-main,.yui-t6 #yui-main{float:left;margin-right:-25em;}.yui-t1 .yui-b{float:left;width:12.30769em;*width:12.00em;}.yui-t1 #yui-main .yui-b{margin-left:13.30769em;*margin-left:13.05em;}.yui-t2 .yui-b{float:left;width:13.8461em;*width:13.50em;}.yui-t2 #yui-main .yui-b{margin-left:14.8461em;*margin-left:14.55em;}.yui-t3 .yui-b{float:left;width:23.0769em;*width:22.50em;}.yui-t3 #yui-main .yui-b{margin-left:24.0769em;*margin-left:23.62em;}.yui-t4 .yui-b{float:right;width:13.8456em;*width:13.50em;}.yui-t4 #yui-main .yui-b{margin-right:14.8456em;*margin-right:14.55em;}.yui-t5 .yui-b{float:right;width:18.4615em;*width:18.00em;}.yui-t5 #yui-main .yui-b{margin-right:19.4615em;*margin-right:19.125em;}.yui-t6 .yui-b{float:right;width:23.0769em;*width:22.50em;}.yui-t6 #yui-main .yui-b{margin-right:24.0769em;*margin-right:23.62em;}.yui-t7 #yui-main .yui-b{display:block;margin:0 0 1em 0;}#yui-main .yui-b{float:none;width:auto;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf,.yui-gc .yui-u,.yui-gd .yui-g,.yui-g .yui-gc .yui-u,.yui-ge .yui-u,.yui-ge .yui-g,.yui-gf .yui-g,.yui-gf .yui-u{float:right;}.yui-g div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first,.yui-ge div.first,.yui-gf div.first,.yui-g .yui-gc div.first,.yui-g .yui-ge div.first,.yui-gc div.first div.first{float:left;}.yui-g .yui-u,.yui-g .yui-g,.yui-g .yui-gb,.yui-g .yui-gc,.yui-g .yui-gd,.yui-g .yui-ge,.yui-g .yui-gf{width:49.1%;}.yui-gb .yui-u,.yui-g .yui-gb .yui-u,.yui-gb .yui-g,.yui-gb .yui-gb,.yui-gb .yui-gc,.yui-gb .yui-gd,.yui-gb .yui-ge,.yui-gb .yui-gf,.yui-gc .yui-u,.yui-gc .yui-g,.yui-gd .yui-u{width:32%;margin-left:1.99%;}.yui-gb .yui-u{*margin-left:1.9%;*width:31.9%;}.yui-gc div.first,.yui-gd .yui-u{width:66%;}.yui-gd div.first{width:32%;}.yui-ge div.first,.yui-gf .yui-u{width:74.2%;}.yui-ge .yui-u,.yui-gf div.first{width:24%;}.yui-g .yui-gb div.first,.yui-gb div.first,.yui-gc div.first,.yui-gd div.first{margin-left:0;}.yui-g .yui-g .yui-u,.yui-gb .yui-g .yui-u,.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u,.yui-ge .yui-g .yui-u,.yui-gf .yui-g .yui-u{width:49%;*width:48.1%;*margin-left:0;}.yui-g .yui-g .yui-u{width:48.1%;}.yui-g .yui-gb div.first,.yui-gb .yui-gb div.first{*margin-right:0;*width:32%;_width:31.7%;}.yui-g .yui-gc div.first,.yui-gd .yui-g{width:66%;}.yui-gb .yui-g div.first{*margin-right:4%;_margin-right:1.3%;}.yui-gb .yui-gc div.first,.yui-gb .yui-gd div.first{*margin-right:0;}.yui-gb .yui-gb .yui-u,.yui-gb .yui-gc .yui-u{*margin-left:1.8%;_margin-left:4%;}.yui-g .yui-gb .yui-u{_margin-left:1.0%;}.yui-gb .yui-gd .yui-u{*width:66%;_width:61.2%;}.yui-gb .yui-gd div.first{*width:31%;_width:29.5%;}.yui-g .yui-gc .yui-u,.yui-gb .yui-gc .yui-u{width:32%;_float:right;margin-right:0;_margin-left:0;}.yui-gb .yui-gc div.first{width:66%;*float:left;*margin-left:0;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf .yui-u{margin:0;}.yui-gb .yui-gb .yui-u{_margin-left:.7%;}.yui-gb .yui-g div.first,.yui-gb .yui-gb div.first{*margin-left:0;}.yui-gc .yui-g .yui-u,.yui-gd .yui-g .yui-u{*width:48.1%;*margin-left:0;} .yui-gb .yui-gd div.first{width:32%;}.yui-g .yui-gd div.first{_width:29.9%;}.yui-ge .yui-g{width:24%;}.yui-gf .yui-g{width:74.2%;}.yui-gb .yui-ge div.yui-u,.yui-gb .yui-gf div.yui-u{float:right;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf div.first{float:left;}.yui-gb .yui-ge .yui-u,.yui-gb .yui-gf div.first{*width:24%;_width:20%;}.yui-gb .yui-ge div.first,.yui-gb .yui-gf .yui-u{*width:73.5%;_width:65.5%;}.yui-ge div.first .yui-gd .yui-u{width:65%;}.yui-ge div.first .yui-gd div.first{width:32%;}#bd:after,.yui-g:after,.yui-gb:after,.yui-gc:after,.yui-gd:after,.yui-ge:after,.yui-gf:after{content:".";display:block;height:0;clear:both;visibility:hidden;}#bd,.yui-g,.yui-gb,.yui-gc,.yui-gd,.yui-ge,.yui-gf{zoom:1;} \ No newline at end of file diff --git a/spec/test_app/public/stylesheets/admin/token-input.css b/spec/test_app/public/stylesheets/admin/token-input.css new file mode 100644 index 0000000..8647a92 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/token-input.css @@ -0,0 +1,109 @@ +/* Example tokeninput style #1: Token vertical list*/ +ul.token-input-list { + overflow: hidden; + height: auto !important; + height: 1%; + width: 400px; + border: 1px solid #999; + cursor: text; + font-size: 12px; + font-family: Verdana; + z-index: 999; + margin: 0; + padding: 0; + background-color: #fff; +} + +ul.token-input-list li { + list-style-type: none; +} + +ul.token-input-list li input { + border: 0; + width: 350px; + padding: 3px 8px; + background-color: white; +} + +li.token-input-token { + overflow: hidden; + height: auto !important; + height: 1%; + margin: 3px; + padding: 3px 5px; + color: #000; + font-weight: bold; + cursor: default; + display: block; +} + +li.token-input-token p { + float: left; + padding: 0; + margin: 0; +} + +li.token-input-token span { + float: right; + color: #777; + cursor: pointer; +} + +li.token-input-selected-token { + background-color: #08844e; + color: #fff; +} + +li.token-input-selected-token span { + color: #bbb; +} + +div.token-input-dropdown { + position: absolute; + width: 400px; + background-color: #fff; + overflow: hidden; + border-left: 1px solid #ccc; + border-right: 1px solid #ccc; + border-bottom: 1px solid #ccc; + cursor: default; + font-size: 12px; + font-family: Verdana; + z-index: 1; +} + +div.token-input-dropdown p { + margin: 0; + padding: 5px; + font-weight: bold; + color: #777; +} + +div.token-input-dropdown ul { + margin: 0; + padding: 0; +} + +div.token-input-dropdown ul li { + background-color: #fff; + padding: 3px; + list-style-type: none; +} + +div.token-input-dropdown ul li.token-input-dropdown-item { + background-color: #fafafa; +} + +div.token-input-dropdown ul li.token-input-dropdown-item2 { + background-color: #fff; +} + +div.token-input-dropdown ul li em { + font-weight: bold; + font-style: normal; +} + +li.token-input-token, div.token-input-dropdown ul li.token-input-selected-dropdown-item { + background-color: #BBDAFD; +} + diff --git a/spec/test_app/public/stylesheets/admin/yui-includes.css b/spec/test_app/public/stylesheets/admin/yui-includes.css new file mode 100755 index 0000000..d1559d2 --- /dev/null +++ b/spec/test_app/public/stylesheets/admin/yui-includes.css @@ -0,0 +1,14 @@ +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.5.2 +*/ +.yuimenubar{visibility:visible;position:static;}.yuimenu .yuimenu,.yuimenubar .yuimenu{visibility:hidden;position:absolute;top:-10000px;left:-10000px;}.yuimenubar li,.yuimenu li{list-style-type:none;}.yuimenubar ul,.yuimenu ul,.yuimenubar li,.yuimenu li,.yuimenu h6,.yuimenubar h6{margin:0;padding:0;}.yuimenuitemlabel,.yuimenubaritemlabel{text-align:left;white-space:nowrap;}.yuimenubar ul{*zoom:1;}.yuimenubar .yuimenu ul{*zoom:normal;}.yuimenubar>.bd>ul:after{content:".";display:block;clear:both;visibility:hidden;height:0;line-height:0;}.yuimenubaritem{float:left;}.yuimenubaritemlabel,.yuimenuitemlabel{display:block;}.yuimenuitemlabel .helptext{font-style:normal;display:block;margin:-1em 0 0 10em;}.yui-menu-shadow{position:absolute;visibility:hidden;z-index:-1;}.yui-menu-shadow-visible{top:2px;right:-3px;left:-3px;bottom:-3px;visibility:visible;}.hide-scrollbars *{overflow:hidden;}.hide-scrollbars select{display:none;}.yuimenu.show-scrollbars,.yuimenubar.show-scrollbars{overflow:visible;}.yuimenu.hide-scrollbars .yui-menu-shadow,.yuimenubar.hide-scrollbars .yui-menu-shadow{overflow:hidden;}.yuimenu.show-scrollbars .yui-menu-shadow,.yuimenubar.show-scrollbars .yui-menu-shadow{overflow:auto;}.yui-skin-sam .yuimenubar{font-size:93%;line-height:2;*line-height:1.9;border:solid 1px #808080;background:url(/images/yui-sprite.png) repeat-x 0 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritem{border-right:solid 1px #ccc;}.yui-skin-sam .yuimenubaritemlabel{padding:0 10px;color:#000;text-decoration:none;cursor:default;border-style:solid;border-color:#808080;border-width:1px 0;*position:relative;margin:-1px 0;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel{padding-right:20px;*display:inline-block;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu{background:url(/images/yui-menubaritem_submenuindicator.png) right center no-repeat;}.yui-skin-sam .yuimenubaritem-selected{background:url(/images/yui-sprite.png) repeat-x 0 -1700px;}.yui-skin-sam .yuimenubaritemlabel-selected{border-color:#7D98B8;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-selected{border-left-width:1px;margin-left:-1px;*left:-1px;}.yui-skin-sam .yuimenubaritemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenubarnav .yuimenubaritemlabel-hassubmenu-disabled{background-image:url(/images/yui-menubaritem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenu{font-size:93%;line-height:1.5;*line-height:1.45;}.yui-skin-sam .yuimenubar .yuimenu,.yui-skin-sam .yuimenu .yuimenu{font-size:100%;}.yui-skin-sam .yuimenu .bd{border:solid 1px #808080;background-color:#fff;}.yui-skin-sam .yuimenu ul{padding:3px 0;border-width:1px 0 0 0;border-color:#ccc;border-style:solid;}.yui-skin-sam .yuimenu ul.first-of-type{border-width:0;}.yui-skin-sam .yuimenu h6{font-weight:bold;border-style:solid;border-color:#ccc;border-width:1px 0 0 0;color:#a4a4a4;padding:3px 10px 0 10px;}.yui-skin-sam .yuimenu ul.hastitle,.yui-skin-sam .yuimenu h6.first-of-type{border-width:0;}.yui-skin-sam .yuimenu .yui-menu-body-scrolled{border-color:#ccc #808080;overflow:hidden;}.yui-skin-sam .yuimenu .topscrollbar,.yui-skin-sam .yuimenu .bottomscrollbar{height:16px;border:solid 1px #808080;background:#fff url(/images/yui-sprite.png) no-repeat 0 0;}.yui-skin-sam .yuimenu .topscrollbar{border-bottom-width:0;background-position:center -950px;}.yui-skin-sam .yuimenu .topscrollbar_disabled{background-position:center -975px;}.yui-skin-sam .yuimenu .bottomscrollbar{border-top-width:0;background-position:center -850px;}.yui-skin-sam .yuimenu .bottomscrollbar_disabled{background-position:center -875px;}.yui-skin-sam .yuimenuitem{_border-bottom:solid 1px #fff;}.yui-skin-sam .yuimenuitemlabel{padding:0 20px;color:#000;text-decoration:none;cursor:default;}.yui-skin-sam .yuimenuitemlabel .helptext{margin-top:-1.5em;*margin-top:-1.45em;}.yui-skin-sam .yuimenuitem-hassubmenu{background-image:url(/images/yui-menuitem_submenuindicator.png);background-position:right center;background-repeat:no-repeat;}.yui-skin-sam .yuimenuitem-checked{background-image:url(/images/yui-menuitem_checkbox.png);background-position:left center;background-repeat:no-repeat;}.yui-skin-sam .yui-menu-shadow-visible{background-color:#000;opacity:.12;*filter:alpha(opacity=12);}.yui-skin-sam .yuimenuitem-selected{background-color:#B3D4FF;}.yui-skin-sam .yuimenuitemlabel-disabled{cursor:default;color:#A6A6A6;}.yui-skin-sam .yuimenuitem-hassubmenu-disabled{background-image:url(/images/yui-menuitem_submenuindicator_disabled.png);}.yui-skin-sam .yuimenuitem-checked-disabled{background-image:url(/images/yui-menuitem_checkbox_disabled.png);} +/* +Copyright (c) 2008, Yahoo! Inc. All rights reserved. +Code licensed under the BSD License: +http://developer.yahoo.net/yui/license.txt +version: 2.5.2 +*/ +.ygtvitem{}.ygtvitem table{margin-bottom:0;border:none;}.ygtvitem td{border:none;padding:0;}.ygtvtn{width:18px;height:22px;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -5600px no-repeat;}.ygtvtm{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -4000px no-repeat;}.ygtvtmh{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -4800px no-repeat;}.ygtvtp{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -6400px no-repeat;}.ygtvtph{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -7200px no-repeat;}.ygtvln{width:18px;height:22px;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -1600px no-repeat;}.ygtvlm{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 0px no-repeat;}.ygtvlmh{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -800px no-repeat;}.ygtvlp{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -2400px no-repeat;}.ygtvlph{width:18px;height:22px;cursor:pointer;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -3200px no-repeat;}.ygtvloading{width:18px;height:22px;background:url(/images/tree-nav-icons/treeview-loading.gif) 0 0 no-repeat;}.ygtvdepthcell{width:18px;height:22px;background:url(/images/tree-nav-icons/treeview-sprite.gif) 0 -8000px no-repeat;}.ygtvblankdepthcell{width:18px;height:22px;}.ygtvchildren{}* html .ygtvchildren{height:2%;}.ygtvlabel,.ygtvlabel:link,.ygtvlabel:visited,.ygtvlabel:hover{margin-left:2px;text-decoration:none;background-color:white;}.ygtvspacer{height:22px;width:12px;} diff --git a/spec/test_app/public/stylesheets/datepicker.css b/spec/test_app/public/stylesheets/datepicker.css new file mode 100644 index 0000000..015b551 --- /dev/null +++ b/spec/test_app/public/stylesheets/datepicker.css @@ -0,0 +1,263 @@ +/* This is a very basic stylesheet for the date-picker. Feel free to create your own. */ + +/* The wrapper div */ +div.datePicker + { + position:absolute; + min-width:24em; + width:24em; + z-index:9999; + text-align:center; + + /* Change the font-size to suit your design's CSS. The following line is for the demo that has a 12px font-size defined on the body tag */ + font:900 0.8em/0.8em Verdana, Sans-Serif; + + /* For Example: If using the YUI font CSS, uncomment the following line to get a 10px font-size within the datePicker */ + /* font:900 77%/77% Verdana; */ + + background:transparent; + + /* Mozilla & Webkit extensions to stop text-selection. Remove if you wish to validate the CSS */ + -moz-user-select:none; + -khtml-user-select:none; + } +/* Styles for the static datePickers */ +div.staticDP + { + position:relative; + top:5px; + left:0; + } +/* The iframe hack to cover selectlists in Internet Explorer <= v6 */ +iframe.iehack + { + position:absolute; + background:#fff; + z-index:9998; + padding:0; + border:0; + display:none; + margin:0; + } +/* The "button" created beside each input for non-static datePickers */ +a.date-picker-control:link, +a.date-picker-control:visited, +a.date-picker-control:hover, +a.date-picker-control:active, +a.date-picker-control:focus + { + /*position:relative;*/ + /* Moz & FF */ + display: -moz-inline-stack; + border:0 none; + padding:0; + margin:0 0 0 4px; + background:transparent url(/images/datepicker/cal.gif) no-repeat 50% 50%; + min-width:16px; + line-height:1; + cursor:pointer; + visibility:visible; + text-decoration:none; + vertical-align:middle; + } +/* Feed IE6 the following rule, IE7 should handle the min-width declared above */ +* html a.date-picker-control + { + width:16px; + } +a.date-picker-control + { + /* IE, Safari & Opera. Seperate CSS rule seems to be required. */ + display:inline-block; + } +a.date-picker-control span + { + display:block; + width:16px; + height:16px; + margin:auto 0; + } +/* The next & previous buttons */ +div.datePicker th span + { + display:inline; + padding:0; + margin:0; + color:#000; + text-align:center; + line-height:1em; + border-width:0; + font-family: georgia, times new roman, palatino, times, bookman, serif; + background:transparent; + font-weight:bold; + cursor:pointer; + } +div.datePicker th span.month-display, +div.datePicker th span.year-display + { + text-transform:uppercase; + letter-spacing:1px; + font:normal 1.2em Verdana, Sans-Serif; + cursor:default; + } +div.datePicker th span.prev-but, +div.datePicker th span.next-but + { + font-size:1.8em; + cursor:pointer !important; + } + +div.datePicker th span.today-but + { + text-align:center; + margin:0 auto; + font:normal 1em Verdana, Sans-Serif; + width:100%; + text-decoration:none; + line-height:1.6em; + text-transform:uppercase; + cursor:pointer !important + } +div.datePicker thead th span.fd-disabled + { + color:#aaa; + cursor:default !important; + } +/* The mon, tue, wed etc day buttons */ +div.datePicker th span.fd-day-header + { + text-align:center; + margin:0 auto; + font:900 1em Verdana, Sans-Serif; + height:1.4em; + width:2em; + text-decoration:none; + text-transform:lowercase; + line-height:1.4em; + } +/* The table */ +div.datePicker table + { + position:relative; + margin:0; + padding:0; + border:1px solid #ccc; + background:#fff url(/images/datepicker/gradient-e5e5e5-ffffff.gif) repeat-x 0 -20px; + text-align:center; + width:100%; + border-spacing:2px; + table-layout:fixed; + border-collapse:separate; + } +/* Common TD & TH styling */ +div.datePicker table td + { + border:1px solid #ccc; + padding:0; + text-align:center; + vertical-align:middle; + /* Opera requires a line-height bigger than 1em in order to redraw properly */ + line-height:1.2em; + cursor:pointer; + background:#fff url(/images/datepicker/gradient-e5e5e5-ffffff.gif) repeat-x 0 -40px; + width:3em; + height:3em !important; + height:2.8em; + outline:none; + } +div.datePicker table th + { + border:0 none; + padding:0; + line-height:1em; + font-weight:bold; + color:#222; + text-align:center; + vertical-align:middle; + } +div.datePicker table td.date-picker-unused + { + background:#fff url(/images/datepicker/backstripes.gif); + border-color:#dcdcdc; + padding:0; + cursor:default !important; + } +div.datePicker table thead th.date-picker-title + { + width:auto; + height:auto; + padding:0.4em 0; + } +/* The "mon tue wed etc" day header button styles */ +div.datePicker table th.date-picker-day-header + { + text-transform:lowercase; + width:3em; + } +div.datePicker table th.date-picker-day-header span + { + display:block; + } +/* The "todays date" style */ +div.datePicker table td.date-picker-today + { + background:#fff url(/images/datepicker/bullet2.gif) no-repeat 0 0; + color:rgb(100,100,100) !important; + } +/* The "selected date" style */ +div.datePicker table td.date-picker-selected-date + { + color:#333 !important; + border-color:#333 !important; + } +/* the "highlight days" style */ +td.date-picker-highlight + { + color:#a86666; + } +/* The date "out of range" style */ +div.datePicker table td.out-of-range + { + color:#ccc !important; + font-style:oblique; + background:#fcfcfc !important; + cursor:default !important; + } +/* The "disabled days" style */ +div.datePicker table td.day-disabled + { + color:#aaa !important; + background:transparent !important; + cursor:default !important; + } +/* The "active cursor" style */ +div.datePicker table tbody td.date-picker-hover + { + background:#fff url(/images/datepicker/bg_header.jpg) no-repeat 0 0; + cursor:pointer; + border-color:rgb(100,130,170); + color:rgb(100,130,170); + } +/* + Quirksmode necessity? + --------------------- + + If your HTML document renders in quirksmode (i.e. has no doctype declaration) + then uncomment the following CSS rule to set a less drastic font-size in IE + +div.datePicker table th, +div.datePicker table td + { + font-size:100%; + } +*/ + +/* Remove the images for Internet Explorer <= v6 using the "* html" hack */ +* html div.datePicker table td + { + background-image:none; + } +* html div.datePicker table td.date-picker-unused + { + background:#f2f2f2; + } diff --git a/spec/test_app/public/stylesheets/jquery.autocomplete.css b/spec/test_app/public/stylesheets/jquery.autocomplete.css new file mode 100644 index 0000000..3ee6bf5 --- /dev/null +++ b/spec/test_app/public/stylesheets/jquery.autocomplete.css @@ -0,0 +1,48 @@ +.ac_results { + padding: 0px; + border: 1px solid black; + background-color: white; + overflow: hidden; + z-index: 99999; +} + +.ac_results ul { + width: 100%; + list-style-position: outside; + list-style: none; + padding: 0; + margin: 0; +} + +.ac_results li { + margin: 0px; + padding: 2px 5px; + cursor: default; + display: block; + /* + if width will be 100% horizontal scrollbar will apear + when scroll mode will be used + */ + /*width: 100%;*/ + font: menu; + font-size: 12px; + /* + it is very important, if line-height not setted or setted + in relative units scroll will be broken in firefox + */ + line-height: 16px; + overflow: hidden; +} + +.ac_loading { + background: white url('indicator.gif') right center no-repeat; +} + +.ac_odd { + background-color: #eee; +} + +.ac_over { + background-color: #0A246A; + color: white; +} \ No newline at end of file diff --git a/spec/test_app/public/stylesheets/scaffold.css b/spec/test_app/public/stylesheets/scaffold.css new file mode 100644 index 0000000..093c209 --- /dev/null +++ b/spec/test_app/public/stylesheets/scaffold.css @@ -0,0 +1,54 @@ +body { background-color: #fff; color: #333; } + +body, 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; } +a:visited { color: #666; } +a:hover { color: #fff; background-color:#000; } + +.fieldWithErrors { + padding: 2px; + background-color: red; + display: table; +} + +#errorExplanation { + width: 400px; + border: 2px solid red; + padding: 7px; + padding-bottom: 12px; + margin-bottom: 20px; + background-color: #f0f0f0; +} + +#errorExplanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px; + background-color: #c00; + color: #fff; +} + +#errorExplanation p { + color: #333; + margin-bottom: 0; + padding: 5px; +} + +#errorExplanation ul li { + font-size: 12px; + list-style: square; +} + diff --git a/spec/test_app/public/stylesheets/screen.css b/spec/test_app/public/stylesheets/screen.css new file mode 100644 index 0000000..49f8449 --- /dev/null +++ b/spec/test_app/public/stylesheets/screen.css @@ -0,0 +1,1195 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, font, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td { + margin: 0; + padding: 0; + border: 0; + outline: 0; + font-weight: inherit; + font-style: inherit; + font-size: 100%; + font-family: inherit; + vertical-align: baseline; +} +*:focus { outline: 0; } +body { + line-height: 1em; + color: black; + background: #ffffff; +} +ol, ul { list-style: none; } +table { + border-collapse: separate; + border-spacing: 0; + vertical-align: middle; +} +caption, th, td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +q, blockquote { quotes: "" ""; } +q:before { content: ""; } +q:after { content: ""; } +blockquote:before { content: ""; } +blockquote:after { content: ""; } +img a { border: none; } +hr { + background: #dddddd; + color: #dddddd; + clear: both; + float: none; + width: 100%; + height: 0.1em; + margin: 0 0 1.45em; + border: none; +} +hr.space { + background: #dddddd; + color: #dddddd; + clear: both; + float: none; + width: 100%; + height: 0.1em; + margin: 0 0 1.45em; + border: none; + background: #ffffff; + color: #ffffff; +} +body { + line-height: 1.5; + font-family: Helvetica Neue, Arial, Helvetica, sans-serif; + color: #333333; + font-size: 75%; +} +h1 { + font-weight: normal; + color: #222222; + font-size: 3em; + line-height: 1; + margin-bottom: 0.5em; +} +h1 img { margin: 0; } +h2 { + font-weight: normal; + color: #222222; + font-size: 2em; + margin-bottom: 0.75em; +} +h3 { + font-weight: normal; + color: #222222; + font-size: 1.5em; + line-height: 1; + margin-bottom: 1em; +} +h4 { + font-weight: normal; + color: #222222; + font-size: 1.2em; + line-height: 1.25; + margin-bottom: 1.25em; +} +h5 { + font-weight: normal; + color: #222222; + font-size: 1em; + font-weight: bold; + margin-bottom: 1.5em; +} +h6 { + font-weight: normal; + color: #222222; + font-size: 1em; + font-weight: bold; +} +h2 img { margin: 0; } +h3 img { margin: 0; } +h4 img { margin: 0; } +h5 img { margin: 0; } +h6 img { margin: 0; } +p { margin: 0 0 1.5em; } +p img.left { + display: inline; + float: left; + margin: 1.5em 1.5em 1.5em 0; + padding: 0; +} +p img.right { + display: inline; + float: right; + margin: 1.5em 0 1.5em 1.5em; + padding: 0; +} +a { + text-decoration: underline; + color: #2e6ab1; +} +blockquote { + margin: 1.5em; + color: #666666; + font-style: italic; +} +strong { font-weight: bold; } +em { font-style: italic; } +dfn { + font-style: italic; + font-weight: bold; +} +sup, sub { line-height: 0; } +abbr, acronym { border-bottom: 1px dotted #666666; } +address { + margin: 0 0 1.5em; + font-style: italic; +} +del { color: #666666; } +pre { + margin: 1.5em 0; + white-space: pre; +} +pre, code, tt { + font: 1em 'andale mono', 'lucida console', monospace; + line-height: 1.5; +} +li ul { margin: 0 1.5em; } +li ol { margin: 0 1.5em; } +ul { + margin: 0 1.5em 1.5em 1.5em; + list-style-type: disc; +} +ol { + margin: 0 1.5em 1.5em 1.5em; + list-style-type: decimal; +} +dl { margin: 0 0 1.5em 0; } +dl dt { font-weight: bold; } +dd { margin-left: 1.5em; } +table { + margin-bottom: 1.4em; + width: 100%; +} +th { font-weight: bold; } +thead th { background: #c3d9ff; } +th, td, caption { padding: 4px 10px 4px 5px; } +tr.even td { background: #e5ecf9; } +tfoot { font-style: italic; } +caption { background: #eeeeee; } +.quiet { color: #666666; } +.loud { color: #111111; } +form p.field { + margin-bottom: 0.5em; + clear: both; +} +form p.field span.req { + color: red; + float: left; + margin-left: 2px; + position: relative; + top: -3px; +} +form p.field input[type=text] { + float: left; + margin: 0 5px 7px 0; +} +form p.field select { + float: left; + margin: 0 5px 7px 0; +} +form p.field.radios { line-height: 150%; } +label { font-weight: bold; } +div#checkout #checkout_form_address #billing label.error { + color: red; + float: left; + text-align: left; + display: inline-block; + top: 0px; + font-size: 11px; + border: none; + padding: 0px; + width: auto; +} +div#checkout #checkout_form_address #shipping label.error { + color: red; + float: left; + text-align: left; + display: inline-block; + top: 0px; + font-size: 11px; + border: none; + padding: 0px; + width: auto; +} +fieldset { margin-bottom: 1em; } +legend { + font-size: 150%; + font-weight: bold; + margin-bottom: 0.5em; +} +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +body { + margin-top: 10px; + background: #ffffff url(../images/body-back.png) top left repeat-x; +} +div.left { + float: left; + width: 49%; +} +div.right { + float: right; + width: 49%; +} +a { outline: none; } +#wrapper { + background: transparent url(../images/wrapper-back.png) top center no-repeat; + padding: 25px 20px 20px; + position: relative; +} +body.two-col #wrapper { background-image: url(../images/wrapper-back-2.png); } +.container { + width: 950px; + margin: 0 auto; + overflow: hidden; + display: block; +} +#sidebar { + display: inline; + float: left; + width: 150px; + margin-right: 10px; + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +#sidebar h3 { margin-bottom: 0.5em; } +body.one-col #content { + display: inline; + float: left; + width: 950px; +} +body.two-col #content { + display: inline; + float: left; + width: 750px; +} +#header { + position: relative; + color: #2e6ab1; + clear: both; +} +#header a { color: #2e6ab1; } +#header a:hover { color: #eeeeee; } +#footer { + padding-top: 2em; + clear: both; +} +#footer div.left { width: 37%; } +#footer div.right { + width: 63%; + text-align: right; +} +h1 { font-size: 2.5em; } +.form-buttons, .clear { clear: both; } +input.title { width: auto; } +p.follow-all { + font-size: 1.3em; + text-align: center; + display: block; +} +p img { + float: left; + margin-right: 5px; + vertical-align: middle; +} +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +.navigation-list { + list-style: none; + margin: 0 0 1.5em -15px; +} +.navigation-list li { margin: 0; } +.navigation-list li a { + cursor: pointer !important; + text-decoration: none; + color: #333333; + display: block; + line-height: 2.5em; + padding-left: 20px; + width: 170px; + white-space: nowrap; + overflow: hidden; +} +.navigation-list li a:hover { background: url(../images/menu-hover.png) right center no-repeat; } +.navigation-list li.current { width: 200px; } +.navigation-list li.current a { + width: 180px; + background: url(../images/menu-current.png) right center no-repeat; + white-space: nowrap; + overflow: hidden; +} +.navigation-list li.current a.root { width: 183px; } +.navigation-list a.root { + color: #222222; + font-size: 1.5em; + text-indent: -5px; + line-height: 2.2em; +} +.breadcrumbs { margin-bottom: 1em; } +.breadcrumbs ul { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; + margin: 0; + padding: 0; + overflow: auto; +} +.breadcrumbs ul li { + margin: 0px; + padding: 0px; + display: inline; +} +.breadcrumbs ul li { + line-height: 20px; + color: #666666; +} +.breadcrumbs ul li a { + text-decoration: none; + padding: 5px 7px; + color: #666666; +} +.breadcrumbs ul li span { + text-decoration: none; + padding: 5px 7px; + color: #666666; +} +.breadcrumbs ul li span { color: #333333; } +div#login-bar { display: inline; } +ul#language-bar { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +ul#language-bar li { + margin: 0px; + padding: 0px; + display: inline; +} +ul#language-bar strong { font-weight: normal; } +ul#nav-bar { + line-height: 50px; + float: right; + clear: both; + font-size: 1.2em; + list-style: none; + margin: 0; + padding: 0; +} +ul#nav-bar li { + float: left; + margin-left: 1em; +} +ul#nav-bar li.cart-indicator a { + padding-right: 40px; + background: transparent url(../images/cart-empty_x32.png) center right no-repeat; + display: block; +} +ul#nav-bar li.cart-indicator a.full { background-image: url(../images/cart-full_x32.png); } +.pagination { + padding-top: 10px; + text-align: right; +} +.pagination a.page { + padding: 0px 5px; + margin: 0px 3px; +} +.pagination span.page { + padding: 0px 5px; + margin: 0px 3px; +} +.pagination a.page { + text-decoration: none; + border: 1px solid #9aafe5; + color: #2e6ab1; +} +.pagination a.page:hover { + border: 1px solid #2b66a5; + color: #000000; +} +.pagination a.page:active { + border: 1px solid #2b66a5; + color: #000000; +} +.pagination a.next_page { font-weight: bold; } +.pagination span.disabled_page { + border: 1px solid #929292; + color: #929292; +} +.pagination span.current_page { + font-weight: bold; + border: 1px solid; + border-color: #162f54; + background-color: #2e6ab1; + color: #ffffff; +} +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +.flash { + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + font-size: 1.3em; + margin-bottom: 1em; + padding: 0.8em; +} +.flash.notice { + background: #ccddff url(../images/shadow_top.png) 0px -50px repeat-x; + color: #556699; + border: 1px solid #99aacc; +} +.flash.errors { + background: #f4b4b4 url(../images/shadow_top.png) 0px -50px repeat-x; + color: #000000; + border: 1px solid #000000; +} +.formError { + font-size: 1.3em; + margin-bottom: 1em; + padding: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + background: #f4b4b4 url(../images/shadow_top.png) 0px -50px repeat-x; + color: #000000; + border: 1px solid #000000; +} +.formError p { margin: 0px; } +.formError ul { margin-bottom: 0px; } +.formError h2 { + font-weight: bold; + font-size: 1em; + margin: 0px; +} +.errorExplanation { + font-size: 1.3em; + margin-bottom: 1em; + padding: 0.8em; + -moz-border-radius: 5px; + -webkit-border-radius: 5px; + border-radius: 5px; + background: #f4b4b4 url(../images/shadow_top.png) 0px -50px repeat-x; + color: #000000; + border: 1px solid #000000; +} +.errorExplanation p { margin: 0px; } +.errorExplanation ul { margin-bottom: 0px; } +.errorExplanation h2 { + font-weight: bold; + font-size: 1em; + margin: 0px; +} +.fieldWithErrors { clear: none; } +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +button, a.button, input.button { + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; + background: #efefef url(../images/buttons/bg-button.png) center left repeat-x !important; + border-style: solid; + border-width: 1px !important; + border-color: #dddddd #999999 #999999 #dddddd !important; + -moz-outline-radius: 0.3em; + color: #111111; + display: inline-block; + font-family: Helvetica Neue, Helvetica, Arial, Sans-serif; + font-size: 1.1em !important; + font-size-adjust: none; + font-stretch: normal; + font-style: normal; + font-variant: normal; + font-weight: normal; + line-height: 1.2em; + margin: 0px; + overflow: visible; + padding: 10px 17px; + text-decoration: none; + text-transform: lowercase; + width: auto; + height: auto; + cursor: pointer; +} +button.primary, a.button.primary, input.button.primary { + font-weight: bold; + color: #000000; +} +button:hover { background-image: url(../images/buttons/bg-button-hover.png) !important; } +a.button:hover { background-image: url(../images/buttons/bg-button-hover.png) !important; } +input.button:hover { background-image: url(../images/buttons/bg-button-hover.png) !important; } +button.large, a.button.large, input.button.large { + -moz-border-radius: 0.3em; + -webkit-border-radius: 0.3em; + border-radius: 0.3em; + font-size: 1.4em !important; + line-height: 1.4em; +} +button.small, a.button.small, input.button.small { + -moz-border-radius: 4px; + -webkit-border-radius: 4px; + border-radius: 4px; + font-size: 0.9em; + line-height: 1.4em; + padding: 5px 10px; +} +button.small img { margin: 0 3px 0 0 !important; } +a.button.small img { margin: 0 3px 0 0 !important; } +input.button.small img { margin: 0 3px 0 0 !important; } +button.update img { margin-right: 7px; } +button.checkout img { margin-right: 7px; } +a.button.update img { margin-right: 7px; } +a.button.checkout img { margin-right: 7px; } +input.button.update img { margin-right: 7px; } +input.button.checkout img { margin-right: 7px; } +button img { vertical-align: middle; } +a.button img { vertical-align: middle; } +input.button img { vertical-align: middle; } +button:focus { outline: none; } +a.button:focus { outline: none; } +input.button:focus { outline: none; } +button::-moz-focus-inner { + padding: 0px; + border: none; +} +p a.button img { margin: 0 5px 0 0; } +p button img { margin: 0 5px 0 0; } +.prices { font-weight: bold; } +.prices #product-details .prices { font-size: 1.25em; } +.price.selling { color: #2e6ab1; } +#product-details .price.selling { font-size: 1.5em; } +.price.diff { + font-style: italic; + font-weight: normal; + color: #666666; +} +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +.product-listing { + list-style: none; + margin: 2em 0px 0px 0px; + padding: 0px; +} +.product-listing li { + -moz-border-radius: 3px; + -webkit-border-radius: 3px; + border-radius: 3px; + height: 180px; + width: 140px; + text-align: center; + float: left; + margin: 10px; + padding: 10px; + border: 1px solid #dddddd; + position: relative; +} +.product-listing li a { + display: block; + text-decoration: none; + color: #111111; +} +.product-listing li a.info { + position: absolute; + bottom: 0px; + right: 0px; + padding: 5px; + width: 150px; + min-height: 60px; + background: #ffffff url(../images/shadow_top.png) 0px -35px repeat-x; + border-top: 1px solid #ffffff; +} +.product-listing li a.info span { display: block; } +.product-listing li:hover { border-color: #1b1b1b; } +.product-listing li:hover a.info { + background: #1b1b1b url(../images/bottom_shine.png) bottom left repeat-x; + color: #ffffff; +} +ul.thumbnails { + margin: 0; + padding: 0; + list-style: none; +} +ul.thumbnails li { + float: left; + margin-right: 5px; + padding: 3px; + border: 1px solid #ffffff; + min-height: 50px; + width: 50px; + position: relative; +} +ul.thumbnails li img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} +ul.thumbnails li:hover { border-color: #cccccc; } +ul.thumbnails li.selected { border-color: #999999; } +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +#product-variants { margin-bottom: 1em; } +#product-variants ul { + list-style: none; + margin: 0; + padding: 0; +} +#product-images { + display: inline; + float: left; + width: 270px; + margin-right: 10px; +} +#product-images h4 { + padding: 6px 0px; + margin: 0px; + font-weight: bold; + clear: both; +} +#product-images #main-image { + min-height: 250px; + position: relative; +} +#product-images #main-image img { + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + margin: auto; +} +#product-description { + display: inline; + float: left; + width: 310px; + margin-right: 10px; + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +#cart-form { + display: inline; + float: left; + width: 270px; +} +#taxon-crumbs { + display: inline; + float: left; + width: 950px; + margin-right: 10px; + display: block; + float: right; + margin-top: 20px; + width: 300px; +} +dl.table-display { + margin: 0; + padding: 0; +} +dl.table-display dt { + float: left; + margin: 0; + padding: 5px; + border-top: 1px solid #dddddd; +} +dl.table-display dd { + float: left; + margin: 0; + padding: 5px; + border-top: 1px solid #dddddd; +} +dl.table-display dt { width: 100px; } +dl.table-display dd { width: 180px; } +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +div#subtotal { + float: right; + width: 49%; + width: auto; + text-align: left; +} +table { border-collapse: collapse; } +table th { + background: transparent; + border-bottom: 1px solid #dddddd; +} +table#cart tr td { + border-bottom: 1px solid #dddddd; + padding: 1em 0; +} +table#cart tr#none td { border-bottom: none; } +table#cart h4 { margin-bottom: 0em; } +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +#signup #new-customer { + display: inline; + float: left; + width: 470px; + margin-right: 10px; +} +#signup #new-customer h2 { margin-bottom: 0.25em; } +#signup #new-customer p { margin-bottom: 10px; } +#signup #new-customer p input.title { + padding: 3px; + margin: 0px; +} +#signup #new-customer input[type=checkbox] { top: 0em; } +#login #existing-customer { + display: inline; + float: left; + width: 470px; + margin-right: 10px; +} +#login #existing-customer h2 { margin-bottom: 0.25em; } +#login #existing-customer p { margin-bottom: 10px; } +#login #existing-customer p input.title { + padding: 3px; + margin: 0px; +} +#login #existing-customer input[type=checkbox] { top: 0em; } +input.openid_url { + background: #ffffff url(../images/openid-inputicon.gif) no-repeat scroll 0pt 50%; + padding-left: 18px; + border: 1px solid #bbbbbb; + font-size: 1.5em; +} +.no_margin_or_padding { + margin: 0; + padding: 0; +} +.leftie { + float: left; + width: 49%; +} +.rightie { + float: right; + width: 49%; +} +.clearfix { + overflow: hidden; + display: inline-block; +} +.clearfix { display: block; } +.nowrap { white-space: nowrap; } +.no-bullets { list-style: none; } +.inline-list { + list-style-type: none; + margin: 0px; + padding: 0px; + display: inline; +} +.inline-list li { + margin: 0px; + padding: 0px; + display: inline; +} +.colborder { + padding-right: 24px; + margin-right: 25px; + border-right: 1px solid #eeeeee; +} +ol.progress-steps { + list-style: none; + margin: 0; + padding: 0; + line-height: 1em; + font-size: 12px; +} +ol.progress-steps li { + margin: 0; + padding: 0; + list-style: none; + display: block; + float: left; + color: #999999; + background-position: top left; + background-repeat: no-repeat; + background-image: url(../images/step-progress/incomplete-incomplete.gif); +} +ol.progress-steps li span { + padding: 5px 14px 7px 24px; + display: block; + float: left; + background-position: top right; + background-repeat: no-repeat; +} +ol.progress-steps li a { + text-decoration: none; + color: #333333; +} +ol.progress-steps li.current-first span { padding-left: 14px; } +ol.progress-steps li.completed-first span { padding-left: 14px; } +ol.progress-steps li.current-first { background-image: url(../images/step-progress/current-first.gif); } +ol.progress-steps li.completed-first { background-image: url(../images/step-progress/completed-first.gif) !important; } +ol.progress-steps li.current { color: #ffffff; } +ol.progress-steps li.current-first { color: #ffffff; } +ol.progress-steps li.current-last { color: #ffffff; } +ol.progress-steps li.completed { background-image: url(../images/step-progress/completed-completed.gif); } +ol.progress-steps li.current { background-image: url(../images/step-progress/completed-current.gif); } +ol.progress-steps li.current-last { background-image: url(../images/step-progress/completed-current.gif); } +ol.progress-steps li.next { background-image: url(../images/step-progress/current-incomplete.gif); } +ol.progress-steps li.next-last { background-image: url(../images/step-progress/current-incomplete.gif); } +ol.progress-steps li.last span { background-image: url(../images/step-progress/incomplete-right.gif); } +ol.progress-steps li.next-last span { background-image: url(../images/step-progress/incomplete-right.gif); } +ol.progress-steps li.current-last span { background-image: url(../images/step-progress/current-right.gif); } +div#checkout { position: relative; } +div#checkout .progress-steps { + position: absolute; + top: 0.5em; + right: 0; +} +div#checkout form { + background-position: top right; + background-repeat: no-repeat; +} +div#checkout #checkout_form_address { background-image: url("../images/steps/2.png"); } +div#checkout #checkout_form_delivery { background-image: url("../images/steps/3.png"); } +div#checkout #checkout_form_address #billing label { + width: 190px; + float: left; + padding-right: 10px; + text-align: right; +} +div#checkout #checkout_form_address #shipping label { + width: 190px; + float: left; + padding-right: 10px; + text-align: right; +} +div#checkout #checkout_form_address #billing input { width: 304px; } +div#checkout #checkout_form_address #shipping input { width: 304px; } +div#checkout #checkout_form_address #billing select { width: 304px; } +div#checkout #checkout_form_address #shipping select { width: 304px; } +div#checkout #checkout_form_address #billing p.checkbox { padding-left: 200px; } +div#checkout #checkout_form_address #shipping p.checkbox { padding-left: 200px; } +div#checkout #checkout_form_address .form-buttons { padding-left: 200px; } +div#checkout #checkout_form_address #billing p.checkbox label { + width: auto !important; + float: none !important; +} +div#checkout #checkout_form_address #shipping p.checkbox label { + width: auto !important; + float: none !important; +} +div#checkout #checkout_form_address #billing p.checkbox input { width: auto !important; } +div#checkout #checkout_form_address #shipping p.checkbox input { width: auto !important; } +div#checkout #checkout_form_payment { background-image: url("../images/steps/5.png"); } +div#checkout #checkout_form_payment select { width: 75px; } +div#checkout #checkout_form_payment #payment { + display: inline; + float: left; + width: 310px; + margin-right: 10px; +} +div#checkout #checkout_form_payment #order_details { + display: inline; + float: left; + width: 470px; + margin-right: 10px; +} +div#checkout #payment-methods { + list-style: none; + display: block; + padding: 0; + margin: 0; + width: 720px; +} +div#checkout #payment-methods li { + display: block; + display: inline; + float: left; + width: 190px; + margin-right: 10px; +} +div#checkout #payment-methods li.last { + display: inline; + float: left; + width: 190px; +} +div#checkout #checkout-summary { + background-color: #c3c9df; + float: right; + margin-top: 10px; + padding: 20px; + width: 180px; +} +div#checkout #checkout-summary { + background-color: #c3c9df; + float: right; + margin-top: 10px; + padding: 20px; + width: 180px; +} diff --git a/spec/test_app/script/rails b/spec/test_app/script/rails new file mode 100755 index 0000000..f138a34 --- /dev/null +++ b/spec/test_app/script/rails @@ -0,0 +1,6 @@ +#!/usr/bin/env ruby1.8 +# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application. + +APP_PATH = File.expand_path('../../config/application', __FILE__) +require File.expand_path('../../config/boot', __FILE__) +require 'rails/commands' diff --git a/spec/test_app/tmp/cache/588/EC0/Spree%3A%3AConfig b/spec/test_app/tmp/cache/588/EC0/Spree%3A%3AConfig new file mode 100644 index 0000000000000000000000000000000000000000..dbbf9771fbf25d8ee3433f020e5016c8af15e6c8 GIT binary patch literal 985 zcmZvb-EPz{5QRZPf(k(k6smS_giwC<>8# z3fzmD^fudzjrLyK8iisCxTl?sC7TGP`ldY4_dLMFgmx8s5;eN!VAw=a>!uNG1jLqt zq$&QeU7=cSQ7=)r6q2}cwPSn3>FlDO4H^7oKJ~U{uZ1zdjnN=sL8E|fg literal 0 HcmV?d00001 diff --git a/spree_faq.gemspec b/spree_faq.gemspec new file mode 100644 index 0000000..1db696b --- /dev/null +++ b/spree_faq.gemspec @@ -0,0 +1,22 @@ +Gem::Specification.new do |s| + s.platform = Gem::Platform::RUBY + s.name = 'spree_faq' + s.version = '3.0.2' + s.summary = 'Adds an easy faq page to your spree site' + s.description = 'With this gem you get an faq page and the management tools to make it very easy to update your faq and reduce the demand on your sites customer service' + s.required_ruby_version = '>= 1.8.7' + + s.author = 'Josh Nussbaum' + s.email = 'joshnuss@gmail.com' + s.homepage = 'http://spreecommerce.com' + s.rubyforge_project = 'spree_faq' + + s.files = Dir['README.md', 'lib/**/*', 'app/**/*', 'config/*', 'db/*'] + s.require_path = 'lib' + s.requirements << 'none' + + s.has_rdoc = false + + s.add_dependency('spree_core', '>= 0.30.1') +end +