lentil 0.0.1.pre

Sign up to get free protection for your applications and to get access to all the features.
Files changed (563) hide show
  1. checksums.yaml +15 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +199 -0
  4. data/Rakefile +43 -0
  5. data/app/assets/images/lentil/icons/MHL-touch-icon-114.png +0 -0
  6. data/app/assets/images/lentil/icons/MHL-touch-icon-144.png +0 -0
  7. data/app/assets/images/lentil/icons/MHL-touch-icon-57.png +0 -0
  8. data/app/assets/images/lentil/icons/MHL-touch-icon-72.png +0 -0
  9. data/app/assets/images/lentil/icons/f_logo.png +0 -0
  10. data/app/assets/images/lentil/icons/twitter-bird-light-bgs.png +0 -0
  11. data/app/assets/images/lentil/loadingsquares.gif +0 -0
  12. data/app/assets/javascripts/active_admin.js +7 -0
  13. data/app/assets/javascripts/lentil.js +3 -0
  14. data/app/assets/javascripts/lentil/addanimatedimages.js +44 -0
  15. data/app/assets/javascripts/lentil/addfancybox.js +152 -0
  16. data/app/assets/javascripts/lentil/addinfinitescroll.js.erb +50 -0
  17. data/app/assets/javascripts/lentil/buttonhandler.js +25 -0
  18. data/app/assets/javascripts/lentil/event_tracking.js.erb +80 -0
  19. data/app/assets/javascripts/lentil/imageerrors.js +8 -0
  20. data/app/assets/javascripts/lentil/images.js +55 -0
  21. data/app/assets/javascripts/lentil/thisorthat.js.erb +129 -0
  22. data/app/assets/stylesheets/active_admin.css.scss +31 -0
  23. data/app/assets/stylesheets/admin/moderation.css.scss +65 -0
  24. data/app/assets/stylesheets/lentil.css.scss +8 -0
  25. data/app/assets/stylesheets/lentil/breakpoint/sass/_components.scss +315 -0
  26. data/app/assets/stylesheets/lentil/breakpoint/sass/_config.scss +37 -0
  27. data/app/assets/stylesheets/lentil/breakpoint/sass/_framework.scss +6 -0
  28. data/app/assets/stylesheets/lentil/breakpoint/sass/_structure.scss +222 -0
  29. data/app/assets/stylesheets/lentil/breakpoint/sass/config.rb +17 -0
  30. data/app/assets/stylesheets/lentil/breakpoint/sass/framework/_grid-core.scss +83 -0
  31. data/app/assets/stylesheets/lentil/breakpoint/sass/framework/_grid-helpers.scss +136 -0
  32. data/app/assets/stylesheets/lentil/breakpoint/sass/framework/_mixins.scss +19 -0
  33. data/app/assets/stylesheets/lentil/breakpoint/sass/framework/_normalize.scss +524 -0
  34. data/app/assets/stylesheets/lentil/breakpoint/sass/framework/_print.scss +19 -0
  35. data/app/assets/stylesheets/lentil/breakpoint/sass/style.scss +12 -0
  36. data/app/assets/stylesheets/lentil/image_animation.css.scss +23 -0
  37. data/app/assets/stylesheets/lentil/images.css.scss +6 -0
  38. data/app/assets/stylesheets/lentil/thisorthat.css.scss +91 -0
  39. data/app/controllers/lentil/application_controller.rb +6 -0
  40. data/app/controllers/lentil/flags_controller.rb +13 -0
  41. data/app/controllers/lentil/images_controller.rb +61 -0
  42. data/app/controllers/lentil/like_votes_controller.rb +13 -0
  43. data/app/controllers/lentil/pages_controller.rb +7 -0
  44. data/app/controllers/lentil/photographers_controller.rb +20 -0
  45. data/app/controllers/lentil/thisorthat_controller.rb +117 -0
  46. data/app/helpers/lentil/application_helper.rb +58 -0
  47. data/app/helpers/lentil/images_helper.rb +23 -0
  48. data/app/helpers/lentil/thisorthat_helper.rb +19 -0
  49. data/app/models/lentil/admin_user.rb +32 -0
  50. data/app/models/lentil/battle.rb +33 -0
  51. data/app/models/lentil/flag.rb +14 -0
  52. data/app/models/lentil/image.rb +174 -0
  53. data/app/models/lentil/license.rb +21 -0
  54. data/app/models/lentil/licensing.rb +16 -0
  55. data/app/models/lentil/like_vote.rb +14 -0
  56. data/app/models/lentil/service.rb +17 -0
  57. data/app/models/lentil/tag.rb +23 -0
  58. data/app/models/lentil/tagging.rb +20 -0
  59. data/app/models/lentil/tagset.rb +24 -0
  60. data/app/models/lentil/tagset_assignment.rb +17 -0
  61. data/app/models/lentil/user.rb +27 -0
  62. data/app/views/admin/lentil_images/_moderation_form_body.html.erb +47 -0
  63. data/app/views/admin/lentil_images/flagging_history.html.erb +33 -0
  64. data/app/views/admin/lentil_images/manual_input.html.erb +6 -0
  65. data/app/views/admin/lentil_images/moderate.html.erb +9 -0
  66. data/app/views/layouts/lentil/_apple_touch_icons.html.erb +1 -0
  67. data/app/views/layouts/lentil/_error.html.erb +9 -0
  68. data/app/views/layouts/lentil/_flag_button.html.erb +10 -0
  69. data/app/views/layouts/lentil/_image_popup.html.erb +34 -0
  70. data/app/views/layouts/lentil/_like_button.html.erb +18 -0
  71. data/app/views/layouts/lentil/_secondary_navigation.html.erb +5 -0
  72. data/app/views/layouts/lentil/_top_navigation.html.erb +26 -0
  73. data/app/views/layouts/lentil/application.html.erb +28 -0
  74. data/app/views/lentil/images/_flagging_modal.html.erb +18 -0
  75. data/app/views/lentil/images/_image_tiles.erb +14 -0
  76. data/app/views/lentil/images/animate.html.erb +19 -0
  77. data/app/views/lentil/images/index.atom.builder +16 -0
  78. data/app/views/lentil/images/index.html.erb +30 -0
  79. data/app/views/lentil/images/index.rss.builder +19 -0
  80. data/app/views/lentil/images/show.html.erb +24 -0
  81. data/app/views/lentil/pages/about.html.erb +9 -0
  82. data/app/views/lentil/photographers/index.html.erb +13 -0
  83. data/app/views/lentil/photographers/show.html.erb +15 -0
  84. data/app/views/lentil/thisorthat/_battle_form.html.erb +44 -0
  85. data/app/views/lentil/thisorthat/battle.html.erb +13 -0
  86. data/app/views/lentil/thisorthat/battle_error.html.erb +3 -0
  87. data/config/locales/en.yml +39 -0
  88. data/config/routes.rb +17 -0
  89. data/db/migrate/20121028023144_create_images.rb +10 -0
  90. data/db/migrate/20121028042738_create_like_votes.rb +10 -0
  91. data/db/migrate/20121028052935_add_like_votes_counter_to_images.rb +5 -0
  92. data/db/migrate/20121028164239_add_sessions_table.rb +12 -0
  93. data/db/migrate/20121030170509_add_url_column_to_images.rb +5 -0
  94. data/db/migrate/20121030170542_add_username_column_to_images.rb +5 -0
  95. data/db/migrate/20121112162243_create_users.rb +11 -0
  96. data/db/migrate/20121112163008_create_services.rb +10 -0
  97. data/db/migrate/20121112163635_remove_username_from_images.rb +9 -0
  98. data/db/migrate/20121112163857_remove_title_from_images.rb +9 -0
  99. data/db/migrate/20121112165849_add_user_id_to_images.rb +5 -0
  100. data/db/migrate/20121112200340_add_service_id_to_users.rb +5 -0
  101. data/db/migrate/20121119210407_create_tags.rb +9 -0
  102. data/db/migrate/20121119210450_create_tagsets.rb +10 -0
  103. data/db/migrate/20121119210538_create_tagset_assignments.rb +12 -0
  104. data/db/migrate/20121119211236_create_taggings.rb +12 -0
  105. data/db/migrate/20121120172450_create_licenses.rb +11 -0
  106. data/db/migrate/20121120172712_create_licensings.rb +12 -0
  107. data/db/migrate/20121120191524_devise_create_admin_users.rb +52 -0
  108. data/db/migrate/20121120191530_create_admin_notes.rb +17 -0
  109. data/db/migrate/20121120191531_move_admin_notes_to_comments.rb +25 -0
  110. data/db/migrate/20121121204450_add_state_to_images.rb +5 -0
  111. data/db/migrate/20121126170008_add_external_identifier_to_images.rb +6 -0
  112. data/db/migrate/20121126192652_add_short_name_to_licenses.rb +6 -0
  113. data/db/migrate/20121126205839_add_long_url_to_images.rb +5 -0
  114. data/db/migrate/20121127154531_create_flags.rb +10 -0
  115. data/db/migrate/20121127160158_add_original_metadata_to_images.rb +5 -0
  116. data/db/migrate/20121127193932_add_index_to_users.rb +5 -0
  117. data/db/migrate/20121127194027_add_index_to_services.rb +5 -0
  118. data/db/migrate/20121127194428_add_index_to_tags.rb +5 -0
  119. data/db/migrate/20121127195059_add_original_datetime_to_images.rb +5 -0
  120. data/db/migrate/20121127210507_add_bio_to_users.rb +5 -0
  121. data/db/migrate/20121127211257_add_staff_like_to_images.rb +5 -0
  122. data/db/migrate/20121128190207_add_moderator_to_images.rb +7 -0
  123. data/db/migrate/20121128213305_add_second_moderation_boolean_to_images.rb +5 -0
  124. data/db/migrate/20121130202753_add_default_for_staff_like.rb +5 -0
  125. data/db/migrate/20121130212917_add_default_for_image_state.rb +5 -0
  126. data/db/migrate/20121206145832_add_staff_tag_to_taggings.rb +5 -0
  127. data/db/migrate/20121213142215_add_images_count_to_users.rb +14 -0
  128. data/db/migrate/20121220151517_create_battles.rb +10 -0
  129. data/db/migrate/20121220155108_add_wins_counter_to_images.rb +5 -0
  130. data/db/migrate/20121220182845_add_losses_counter_to_images.rb +5 -0
  131. data/db/migrate/20130107192518_add_win_pct_to_images.rb +5 -0
  132. data/db/migrate/20130108195949_add_popular_score_to_images.rb +5 -0
  133. data/db/migrate/20130116145103_add_harvest_to_tagsets.rb +5 -0
  134. data/db/migrate/20130130194955_add_file_harvested_date_field_to_images.rb +6 -0
  135. data/db/migrate/20130306144752_add_donor_agreement_submitted_to_images.rb +5 -0
  136. data/db/migrate/20130306145013_add_donor_agreement_failed_to_images.rb +5 -0
  137. data/db/migrate/20130403135640_add_failed_file_checks_to_images.rb +6 -0
  138. data/db/migrate/20130412195348_namespace_tables.rb +16 -0
  139. data/db/migrate/20130413005943_namespace_licensings.rb +5 -0
  140. data/db/migrate/20130506204728_add_donor_agreement_rejected_to_images.rb +5 -0
  141. data/db/migrate/20130506205348_add_do_not_request_donation_to_lentil_images.rb +5 -0
  142. data/db/seeds.rb +5 -0
  143. data/lib/generators/lentil/USAGE +8 -0
  144. data/lib/generators/lentil/install_generator.rb +85 -0
  145. data/lib/generators/lentil/templates/README.md +19 -0
  146. data/lib/generators/lentil/templates/active_admin.rb +150 -0
  147. data/lib/generators/lentil/templates/devise.rb +232 -0
  148. data/lib/generators/lentil/templates/kaminari.rb +3 -0
  149. data/lib/generators/lentil/templates/lentil_config.yml +33 -0
  150. data/lib/lentil.rb +24 -0
  151. data/lib/lentil/admin/admin_user.rb +24 -0
  152. data/lib/lentil/admin/dashboard.rb +116 -0
  153. data/lib/lentil/admin/flags.rb +17 -0
  154. data/lib/lentil/admin/images.rb +209 -0
  155. data/lib/lentil/admin/tags.rb +18 -0
  156. data/lib/lentil/admin/tagsets.rb +51 -0
  157. data/lib/lentil/admin/user.rb +20 -0
  158. data/lib/lentil/admin/view_helpers.rb +11 -0
  159. data/lib/lentil/engine.rb +22 -0
  160. data/lib/lentil/instagram_harvester.rb +249 -0
  161. data/lib/lentil/popularity_calculator.rb +63 -0
  162. data/lib/lentil/version.rb +3 -0
  163. data/lib/tasks/auto_annotate_models.rake +20 -0
  164. data/lib/tasks/image_services.rake +129 -0
  165. data/lib/tasks/lentil_tasks.rake +10 -0
  166. data/lib/tasks/popularity.rake +16 -0
  167. data/test/dummy/README.rdoc +261 -0
  168. data/test/dummy/Rakefile +7 -0
  169. data/test/dummy/app/assets/javascripts/application.js +15 -0
  170. data/test/dummy/app/assets/stylesheets/application.css.scss +1 -0
  171. data/test/dummy/app/controllers/application_controller.rb +3 -0
  172. data/test/dummy/app/helpers/application_helper.rb +2 -0
  173. data/test/dummy/config.ru +4 -0
  174. data/test/dummy/config/application.rb +59 -0
  175. data/test/dummy/config/boot.rb +10 -0
  176. data/test/dummy/config/database.yml +25 -0
  177. data/test/dummy/config/environment.rb +5 -0
  178. data/test/dummy/config/environments/development.rb +37 -0
  179. data/test/dummy/config/environments/production.rb +67 -0
  180. data/test/dummy/config/environments/test.rb +37 -0
  181. data/test/dummy/config/initializers/active_admin.rb +150 -0
  182. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  183. data/test/dummy/config/initializers/devise.rb +232 -0
  184. data/test/dummy/config/initializers/inflections.rb +15 -0
  185. data/test/dummy/config/initializers/kaminari.rb +3 -0
  186. data/test/dummy/config/initializers/mime_types.rb +5 -0
  187. data/test/dummy/config/initializers/secret_token.rb +7 -0
  188. data/test/dummy/config/initializers/session_store.rb +8 -0
  189. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  190. data/test/dummy/config/lentil_config.yml +30 -0
  191. data/test/dummy/config/locales/en.yml +5 -0
  192. data/test/dummy/config/routes.rb +9 -0
  193. data/test/dummy/db/schema.rb +195 -0
  194. data/test/dummy/db/seeds.rb +1 -0
  195. data/test/dummy/db/test.sqlite3 +0 -0
  196. data/test/dummy/log/test.log +10235 -0
  197. data/test/dummy/public/404.html +26 -0
  198. data/test/dummy/public/422.html +26 -0
  199. data/test/dummy/public/500.html +25 -0
  200. data/test/dummy/public/favicon.ico +0 -0
  201. data/test/dummy/script/rails +6 -0
  202. data/test/dummy/tmp/cache/assets/C42/6B0/sprockets%2Ff9428783b785862eb53346b864f94428 +0 -0
  203. data/test/dummy/tmp/cache/assets/C48/E70/sprockets%2Fa7be1700e70899163027f63a25844c02 +0 -0
  204. data/test/dummy/tmp/cache/assets/C57/560/sprockets%2F1f547a440537aec8d738c93894407105 +0 -0
  205. data/test/dummy/tmp/cache/assets/C64/FE0/sprockets%2F64416e104b07dc260675009a5aa802c1 +0 -0
  206. data/test/dummy/tmp/cache/assets/C6C/080/sprockets%2F2116707a968e8208e090b121181afc0a +0 -0
  207. data/test/dummy/tmp/cache/assets/C6F/5C0/sprockets%2Fddc2132bb0b628079c5065081c817551 +0 -0
  208. data/test/dummy/tmp/cache/assets/C7B/090/sprockets%2F96c14f0b10f122605c2c48b5277865e6 +0 -0
  209. data/test/dummy/tmp/cache/assets/C83/600/sprockets%2F68b2320f62db97898602c88ab351b154 +0 -0
  210. data/test/dummy/tmp/cache/assets/C8D/0B0/sprockets%2F4086552147c1d9af9c66e72943d63b82 +0 -0
  211. data/test/dummy/tmp/cache/assets/C92/100/sprockets%2F36490a1ee805e37f098a7817e6c95526 +0 -0
  212. data/test/dummy/tmp/cache/assets/C96/970/sprockets%2F0829123a4f1a0c4102c81c9a35c02c98 +0 -0
  213. data/test/dummy/tmp/cache/assets/C99/8E0/sprockets%2Fe953726264248e339078be7cc7926e4f +0 -0
  214. data/test/dummy/tmp/cache/assets/CA6/380/sprockets%2F0db015389c4847b44149da5432ee600e +0 -0
  215. data/test/dummy/tmp/cache/assets/CAC/100/sprockets%2F9399d899650c546f87d34e233caf9977 +0 -0
  216. data/test/dummy/tmp/cache/assets/CB2/410/sprockets%2F95d0566e48bb62f4bf44364504421e9a +0 -0
  217. data/test/dummy/tmp/cache/assets/CB5/320/sprockets%2Fcc2889b817f6b8603540cd71e6616b50 +0 -0
  218. data/test/dummy/tmp/cache/assets/CB9/990/sprockets%2Faf8ad756710f9583563033dd94c728c0 +0 -0
  219. data/test/dummy/tmp/cache/assets/CC6/F80/sprockets%2Fd5e909a571443a22cf0dc0c113a94114 +0 -0
  220. data/test/dummy/tmp/cache/assets/CC8/C20/sprockets%2F6354de7687421eeda9c430397894f8f0 +0 -0
  221. data/test/dummy/tmp/cache/assets/CC9/7B0/sprockets%2Ffaa30a33ae1698f27018d11e3f072233 +0 -0
  222. data/test/dummy/tmp/cache/assets/CCF/5F0/sprockets%2F5d62451bc086a25070b4ea73c387d1a5 +0 -0
  223. data/test/dummy/tmp/cache/assets/CD5/A00/sprockets%2F9c4914e228af6400d302b6cd283f900e +0 -0
  224. data/test/dummy/tmp/cache/assets/CD6/170/sprockets%2F3554b0cf72c07f591dcb54630607d0a9 +0 -0
  225. data/test/dummy/tmp/cache/assets/CD6/F30/sprockets%2F23191ae5e95d7e0e0771b7033a1097af +0 -0
  226. data/test/dummy/tmp/cache/assets/CE5/210/sprockets%2Fdb0122cf42e7810fe0799874be09644e +0 -0
  227. data/test/dummy/tmp/cache/assets/CE5/650/sprockets%2F8ab512c9b33ac90e699b73469d71f061 +0 -0
  228. data/test/dummy/tmp/cache/assets/CE6/FE0/sprockets%2F73ec02022749e817b83909f60cce7a5f +0 -0
  229. data/test/dummy/tmp/cache/assets/CE7/610/sprockets%2F08cbe5246a49c4599797a0224fd246ea +0 -0
  230. data/test/dummy/tmp/cache/assets/CE7/F00/sprockets%2Fa74a53552b73e97b67ad19ce7660055f +0 -0
  231. data/test/dummy/tmp/cache/assets/CEA/A40/sprockets%2Fdfdd64331199cfc265779fd03241377c +0 -0
  232. data/test/dummy/tmp/cache/assets/CEA/D30/sprockets%2F45a3a8537165a7657e4ed46f8bdb0593 +0 -0
  233. data/test/dummy/tmp/cache/assets/CEC/830/sprockets%2F77ad86593cd9332af1407493e5c39c5b +0 -0
  234. data/test/dummy/tmp/cache/assets/CEC/C10/sprockets%2Fc193f41bd81159ae9ef7b0385250e789 +0 -0
  235. data/test/dummy/tmp/cache/assets/CED/250/sprockets%2F28b6d357c282e6867362ed05881dfe2b +0 -0
  236. data/test/dummy/tmp/cache/assets/CED/460/sprockets%2Fd37d356a7d06d0609ea3f7628496d29d +0 -0
  237. data/test/dummy/tmp/cache/assets/CF9/DA0/sprockets%2Fedb69283f09967db46c74b72ae179494 +0 -0
  238. data/test/dummy/tmp/cache/assets/CFB/160/sprockets%2F98a9093839b570dcc8997d274dbbc465 +0 -0
  239. data/test/dummy/tmp/cache/assets/D03/CD0/sprockets%2F2cd0353d32bc3c4284ef8537a3b47f22 +0 -0
  240. data/test/dummy/tmp/cache/assets/D04/360/sprockets%2Fddeca47fb0c8741454b26453d41c8015 +0 -0
  241. data/test/dummy/tmp/cache/assets/D04/C00/sprockets%2Fca82ed20399235d2c48dbb6d1620732d +0 -0
  242. data/test/dummy/tmp/cache/assets/D04/F50/sprockets%2F1dada65d112db8475da0768b01971a94 +0 -0
  243. data/test/dummy/tmp/cache/assets/D0D/B10/sprockets%2F3de9d42f71f1bc23221b69171e90ed67 +0 -0
  244. data/test/dummy/tmp/cache/assets/D1B/590/sprockets%2Fbe6ac6f9a700610d5ba87966e577077d +0 -0
  245. data/test/dummy/tmp/cache/assets/D1E/680/sprockets%2F509a2e8767cd429ea59a1b689d4ab484 +0 -0
  246. data/test/dummy/tmp/cache/assets/D27/B70/sprockets%2F5780a94fb908448ed3e800e63fd877de +0 -0
  247. data/test/dummy/tmp/cache/assets/D2E/B70/sprockets%2Fb05c50d8309cf7e7c006b344fbed0107 +0 -0
  248. data/test/dummy/tmp/cache/assets/D32/340/sprockets%2Fbfd4a939f123425ff33a40a76032ded2 +0 -0
  249. data/test/dummy/tmp/cache/assets/D34/C30/sprockets%2F715a4379b39f2577210c15affca3bdc1 +0 -0
  250. data/test/dummy/tmp/cache/assets/D38/440/sprockets%2Fc906c171e7aa8ba93ec3219ce4f04705 +0 -0
  251. data/test/dummy/tmp/cache/assets/D38/B20/sprockets%2F2b1c2ef9ddf068ab0174d4568091ea62 +0 -0
  252. data/test/dummy/tmp/cache/assets/D3B/EC0/sprockets%2Fc3ef1b053f9f177d9141cc375bf61c50 +0 -0
  253. data/test/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  254. data/test/dummy/tmp/cache/assets/D56/BE0/sprockets%2F7777b5cfe624ec519525fe82da08f7e6 +0 -0
  255. data/test/dummy/tmp/cache/assets/D61/290/sprockets%2Fdf8e43ab35b1467495b10ad40c97bb1b +0 -0
  256. data/test/dummy/tmp/cache/assets/D66/AD0/sprockets%2F630aed9dbe5fb89243b0c040af3670e7 +0 -0
  257. data/test/dummy/tmp/cache/assets/D69/E10/sprockets%2F48900c1edbfe227d110f8050fbdd97f4 +0 -0
  258. data/test/dummy/tmp/cache/assets/D6D/AB0/sprockets%2F7138214dfee4490b54377eecc4cbfe11 +0 -0
  259. data/test/dummy/tmp/cache/assets/D6F/EF0/sprockets%2F0466d0a8ac4be2e9114ff4e82af38d84 +0 -0
  260. data/test/dummy/tmp/cache/assets/D73/040/sprockets%2Fcab4ce19553a2852a2ecec47f1e87568 +0 -0
  261. data/test/dummy/tmp/cache/assets/D74/490/sprockets%2Fa17a51fbc23c1a3648e9f6fec8f62943 +0 -0
  262. data/test/dummy/tmp/cache/assets/D74/680/sprockets%2F3dd8cd62caf32217aa89f897b0eb2818 +0 -0
  263. data/test/dummy/tmp/cache/assets/D7A/930/sprockets%2F6be8ba37ee48b21a9ab604565dfd9775 +0 -0
  264. data/test/dummy/tmp/cache/assets/D7A/A90/sprockets%2Ffec462cdc03e47621953fc8eb9e6547a +0 -0
  265. data/test/dummy/tmp/cache/assets/D8B/ED0/sprockets%2Fcc585faf0bcbb142f7125444e4fa6a02 +0 -0
  266. data/test/dummy/tmp/cache/assets/D90/440/sprockets%2Fb2aa1e118ce5bd06dee76be633562d42 +0 -0
  267. data/test/dummy/tmp/cache/assets/D91/080/sprockets%2Fbcca522c6302f184f12fe0e8a7d7e71a +0 -0
  268. data/test/dummy/tmp/cache/assets/D94/FD0/sprockets%2F2b120edc1ebea9c0f72d9be11d778390 +0 -0
  269. data/test/dummy/tmp/cache/assets/D95/2B0/sprockets%2F89dbd7378a1d1062e45dcc3df7a3a11c +0 -0
  270. data/test/dummy/tmp/cache/assets/D9C/1C0/sprockets%2F6d2b0db50dd2acf27667a48159c9f6ab +0 -0
  271. data/test/dummy/tmp/cache/assets/D9C/8A0/sprockets%2Fc76d2440ebeb87ab52dfe9d80bf10086 +0 -0
  272. data/test/dummy/tmp/cache/assets/D9D/380/sprockets%2Fb04c1714897d76abeca81fa0a37f8e6b +0 -0
  273. data/test/dummy/tmp/cache/assets/D9D/5B0/sprockets%2Fddcba2ec2b3037ef281e781a486de980 +0 -0
  274. data/test/dummy/tmp/cache/assets/D9F/300/sprockets%2Fc13fc73ceafa45876a901b3e775b83ae +0 -0
  275. data/test/dummy/tmp/cache/assets/DB0/FD0/sprockets%2F996ad98b7351ad4d9bd4b485a7ae9fa3 +0 -0
  276. data/test/dummy/tmp/cache/assets/DB1/8D0/sprockets%2F6cf903e8ff571c4d957e479cac1bc19d +0 -0
  277. data/test/dummy/tmp/cache/assets/DB3/1D0/sprockets%2F22cba3622ce0621f3eba0dd7e1aa089f +0 -0
  278. data/test/dummy/tmp/cache/assets/DB4/0B0/sprockets%2Fe8f58b1269ee313ff8b892bca727ede6 +0 -0
  279. data/test/dummy/tmp/cache/assets/DB6/F30/sprockets%2Fb6999585996e0f4bff328ba3addd17fb +0 -0
  280. data/test/dummy/tmp/cache/assets/DC1/020/sprockets%2Fbf6419ab7cf802a47da9ec4d1040cd4b +0 -0
  281. data/test/dummy/tmp/cache/assets/DC4/040/sprockets%2F0c65ff4bf893dd905d30aa129f4abca2 +0 -0
  282. data/test/dummy/tmp/cache/assets/DCA/030/sprockets%2F0bc7d1ffb47f42b36bc9abec83b58442 +0 -0
  283. data/test/dummy/tmp/cache/assets/DCB/D90/sprockets%2Fcfca0c746a29e28e6507eb312e7ec5bd +0 -0
  284. data/test/dummy/tmp/cache/assets/DCC/EA0/sprockets%2F3c7d9707a1daca88216a8ffc0fa8e4a3 +0 -0
  285. data/test/dummy/tmp/cache/assets/DCE/E00/sprockets%2F5f20b88da0ea9a18a05ee2f4d03f97ff +0 -0
  286. data/test/dummy/tmp/cache/assets/DCE/EC0/sprockets%2Ff2ec34a23c62dd857e1cf1df5966bc3b +0 -0
  287. data/test/dummy/tmp/cache/assets/DD3/E70/sprockets%2F6570fc1bef16b28caa54448c9deffa29 +0 -0
  288. data/test/dummy/tmp/cache/assets/DD7/F60/sprockets%2Fba89e9841faeba02ba74a8ed492f287e +0 -0
  289. data/test/dummy/tmp/cache/assets/DDA/900/sprockets%2F24705bef559fbf6f8738b7ab9b3f0faa +0 -0
  290. data/test/dummy/tmp/cache/assets/DDA/DD0/sprockets%2F74f3d35d3bacb479b95d56d17bafe75f +0 -0
  291. data/test/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  292. data/test/dummy/tmp/cache/assets/DDC/9A0/sprockets%2F6b6d65eb6c891e5d6b5c1af73ae98ca6 +0 -0
  293. data/test/dummy/tmp/cache/assets/DDE/9B0/sprockets%2F890f41b9acdd3f93bd6ef7ae908ce472 +0 -0
  294. data/test/dummy/tmp/cache/assets/DE6/210/sprockets%2Fa2d10a00bca3a1e477d6dc95effc35c1 +0 -0
  295. data/test/dummy/tmp/cache/assets/DEE/C90/sprockets%2Ffca14d24400af9ec6deca6ec402953cb +0 -0
  296. data/test/dummy/tmp/cache/assets/DFB/980/sprockets%2F73cd2a8ad913ea8aece63bb39e3b72c6 +0 -0
  297. data/test/dummy/tmp/cache/assets/E03/CF0/sprockets%2Ffd9ccc8eca5b28ea8c175587a1c37cb3 +0 -0
  298. data/test/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  299. data/test/dummy/tmp/cache/assets/E07/0F0/sprockets%2F96ac3cc2bdaae9cde264974ef77d2c81 +0 -0
  300. data/test/dummy/tmp/cache/assets/E0F/E90/sprockets%2F8e7db2bac32a0e9cac06b43ab5d242ab +0 -0
  301. data/test/dummy/tmp/cache/assets/E25/820/sprockets%2Fd3b6a937cfa7e45cffc316bae06db5b0 +0 -0
  302. data/test/dummy/tmp/cache/assets/E2D/020/sprockets%2Fcbafddc9ed34b5bb8d1e300c55b488e9 +0 -0
  303. data/test/dummy/tmp/cache/assets/E33/300/sprockets%2Fb751f7e95e5efaedb23aef5b5069bd2c +0 -0
  304. data/test/dummy/tmp/cache/assets/E39/490/sprockets%2Ff0d1f807d9aeda4a98600cb9fe9df7cc +0 -0
  305. data/test/dummy/tmp/cache/assets/E68/D50/sprockets%2Fbb4b566ad8ba5fa7cf5e547cedfe0f95 +0 -0
  306. data/test/dummy/tmp/cache/sass/09ef2509826c8e6328e00a46ab2d431530905427/_base.scssc +0 -0
  307. data/test/dummy/tmp/cache/sass/09ef2509826c8e6328e00a46ab2d431530905427/_sprite-img.scssc +0 -0
  308. data/test/dummy/tmp/cache/sass/18aae862c6b8d844ecb0d28099e3c6dc22a78390/_components.scssc +0 -0
  309. data/test/dummy/tmp/cache/sass/18aae862c6b8d844ecb0d28099e3c6dc22a78390/_config.scssc +0 -0
  310. data/test/dummy/tmp/cache/sass/18aae862c6b8d844ecb0d28099e3c6dc22a78390/_framework.scssc +0 -0
  311. data/test/dummy/tmp/cache/sass/18aae862c6b8d844ecb0d28099e3c6dc22a78390/_structure.scssc +0 -0
  312. data/test/dummy/tmp/cache/sass/18aae862c6b8d844ecb0d28099e3c6dc22a78390/style.scssc +0 -0
  313. data/test/dummy/tmp/cache/sass/230bfc8f182635ad4b3a335d489af9a06274afb8/application.css.scssc +0 -0
  314. data/test/dummy/tmp/cache/sass/2a4cafc997677a5e0158c4d4a79d2ab3f4ff6997/_grid-core.scssc +0 -0
  315. data/test/dummy/tmp/cache/sass/2a4cafc997677a5e0158c4d4a79d2ab3f4ff6997/_grid-helpers.scssc +0 -0
  316. data/test/dummy/tmp/cache/sass/2a4cafc997677a5e0158c4d4a79d2ab3f4ff6997/_mixins.scssc +0 -0
  317. data/test/dummy/tmp/cache/sass/2a4cafc997677a5e0158c4d4a79d2ab3f4ff6997/_normalize.scssc +0 -0
  318. data/test/dummy/tmp/cache/sass/2a4cafc997677a5e0158c4d4a79d2ab3f4ff6997/_print.scssc +0 -0
  319. data/test/dummy/tmp/cache/sass/2fc48581832b599e78863798b316800e2f081db8/_css3.scssc +0 -0
  320. data/test/dummy/tmp/cache/sass/2fc48581832b599e78863798b316800e2f081db8/_support.scssc +0 -0
  321. data/test/dummy/tmp/cache/sass/2fc48581832b599e78863798b316800e2f081db8/_typography.scssc +0 -0
  322. data/test/dummy/tmp/cache/sass/2fc48581832b599e78863798b316800e2f081db8/_utilities.scssc +0 -0
  323. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_appearance.scssc +0 -0
  324. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_background-clip.scssc +0 -0
  325. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_background-origin.scssc +0 -0
  326. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_background-size.scssc +0 -0
  327. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_border-radius.scssc +0 -0
  328. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_box-shadow.scssc +0 -0
  329. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_box-sizing.scssc +0 -0
  330. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_box.scssc +0 -0
  331. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_columns.scssc +0 -0
  332. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_filter.scssc +0 -0
  333. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_font-face.scssc +0 -0
  334. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_hyphenation.scssc +0 -0
  335. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_images.scssc +0 -0
  336. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_inline-block.scssc +0 -0
  337. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_opacity.scssc +0 -0
  338. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_regions.scssc +0 -0
  339. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_shared.scssc +0 -0
  340. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_text-shadow.scssc +0 -0
  341. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_transform.scssc +0 -0
  342. data/test/dummy/tmp/cache/sass/3a054fa2dd9c968492f5a0cb990ea7fe73be8836/_transition.scssc +0 -0
  343. data/test/dummy/tmp/cache/sass/3b11a8de81207d23d358103aa6b295021cc4f559/_contrast.scssc +0 -0
  344. data/test/dummy/tmp/cache/sass/4fafd6ccd5f325d6297db249d1acfce25c894abe/_compass.scssc +0 -0
  345. data/test/dummy/tmp/cache/sass/619a076775683b6e082ab3e83ee70dd4025b71ce/fancybox.cssc +0 -0
  346. data/test/dummy/tmp/cache/sass/6a181fabeabb4ad8135cf2bd3fa15f5039ab85a9/_utilities.scssc +0 -0
  347. data/test/dummy/tmp/cache/sass/6f4451653f8c03db4c183f13952595ad7fc9a7a5/_alternating-rows-and-columns.scssc +0 -0
  348. data/test/dummy/tmp/cache/sass/6f4451653f8c03db4c183f13952595ad7fc9a7a5/_borders.scssc +0 -0
  349. data/test/dummy/tmp/cache/sass/6f4451653f8c03db4c183f13952595ad7fc9a7a5/_scaffolding.scssc +0 -0
  350. data/test/dummy/tmp/cache/sass/6f8312e52a18e9753d5d08c869f5c3bec77f12b3/chosen.css.sassc +0 -0
  351. data/test/dummy/tmp/cache/sass/703c74442f96736be7a09968192044436254f4e2/bootstrap-responsive.scssc +0 -0
  352. data/test/dummy/tmp/cache/sass/703c74442f96736be7a09968192044436254f4e2/bootstrap.scssc +0 -0
  353. data/test/dummy/tmp/cache/sass/731447a6308f18f1769d254075093bb72c24f347/image_animation.css.scssc +0 -0
  354. data/test/dummy/tmp/cache/sass/731447a6308f18f1769d254075093bb72c24f347/images.css.scssc +0 -0
  355. data/test/dummy/tmp/cache/sass/731447a6308f18f1769d254075093bb72c24f347/thisorthat.css.scssc +0 -0
  356. data/test/dummy/tmp/cache/sass/81b75274929b072edf6f16f0144d09b81c0ec6cb/_color.scssc +0 -0
  357. data/test/dummy/tmp/cache/sass/81b75274929b072edf6f16f0144d09b81c0ec6cb/_general.scssc +0 -0
  358. data/test/dummy/tmp/cache/sass/81b75274929b072edf6f16f0144d09b81c0ec6cb/_sprites.scssc +0 -0
  359. data/test/dummy/tmp/cache/sass/81b75274929b072edf6f16f0144d09b81c0ec6cb/_tables.scssc +0 -0
  360. data/test/dummy/tmp/cache/sass/a9ceb8ca2f3605f188194e487b24c01a1853c7e8/_grid-background.scssc +0 -0
  361. data/test/dummy/tmp/cache/sass/d53eea4db5c445904dd2d1926d6eea4bbca119f9/_bullets.scssc +0 -0
  362. data/test/dummy/tmp/cache/sass/d53eea4db5c445904dd2d1926d6eea4bbca119f9/_horizontal-list.scssc +0 -0
  363. data/test/dummy/tmp/cache/sass/d53eea4db5c445904dd2d1926d6eea4bbca119f9/_inline-block-list.scssc +0 -0
  364. data/test/dummy/tmp/cache/sass/d53eea4db5c445904dd2d1926d6eea4bbca119f9/_inline-list.scssc +0 -0
  365. data/test/dummy/tmp/cache/sass/d8b9a6cd27d9e74c47290b0b43e75f4003d5e84b/lentil.css.scssc +0 -0
  366. data/test/dummy/tmp/cache/sass/e8cb3fe0dc661de96e682e25b9bbeaf97d6a8698/_links.scssc +0 -0
  367. data/test/dummy/tmp/cache/sass/e8cb3fe0dc661de96e682e25b9bbeaf97d6a8698/_lists.scssc +0 -0
  368. data/test/dummy/tmp/cache/sass/e8cb3fe0dc661de96e682e25b9bbeaf97d6a8698/_text.scssc +0 -0
  369. data/test/dummy/tmp/cache/sass/e8cb3fe0dc661de96e682e25b9bbeaf97d6a8698/_vertical_rhythm.scssc +0 -0
  370. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_accordion.scssc +0 -0
  371. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_alerts.scssc +0 -0
  372. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_breadcrumbs.scssc +0 -0
  373. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_button-groups.scssc +0 -0
  374. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_buttons.scssc +0 -0
  375. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_carousel.scssc +0 -0
  376. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_close.scssc +0 -0
  377. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_code.scssc +0 -0
  378. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_component-animations.scssc +0 -0
  379. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_dropdowns.scssc +0 -0
  380. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_forms.scssc +0 -0
  381. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_grid.scssc +0 -0
  382. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_hero-unit.scssc +0 -0
  383. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_labels-badges.scssc +0 -0
  384. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_layouts.scssc +0 -0
  385. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_media.scssc +0 -0
  386. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_mixins.scssc +0 -0
  387. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_modals.scssc +0 -0
  388. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_navbar.scssc +0 -0
  389. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_navs.scssc +0 -0
  390. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_pager.scssc +0 -0
  391. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_pagination.scssc +0 -0
  392. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_popovers.scssc +0 -0
  393. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_progress-bars.scssc +0 -0
  394. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_reset.scssc +0 -0
  395. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_responsive-1200px-min.scssc +0 -0
  396. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_responsive-767px-max.scssc +0 -0
  397. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_responsive-768px-979px.scssc +0 -0
  398. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_responsive-navbar.scssc +0 -0
  399. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_responsive-utilities.scssc +0 -0
  400. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_scaffolding.scssc +0 -0
  401. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_sprites.scssc +0 -0
  402. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_tables.scssc +0 -0
  403. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_thumbnails.scssc +0 -0
  404. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_tooltip.scssc +0 -0
  405. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_type.scssc +0 -0
  406. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_utilities.scssc +0 -0
  407. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_variables.scssc +0 -0
  408. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/_wells.scssc +0 -0
  409. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/bootstrap.scssc +0 -0
  410. data/test/dummy/tmp/cache/sass/effeda9621a1f8587c33f3f59e511b0a59ff7bb4/responsive.scssc +0 -0
  411. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_clearfix.scssc +0 -0
  412. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_float.scssc +0 -0
  413. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_hacks.scssc +0 -0
  414. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_min.scssc +0 -0
  415. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_reset.scssc +0 -0
  416. data/test/dummy/tmp/cache/sass/f785cff4f2efc02e3a7a52ccf822a563c511b793/_tag-cloud.scssc +0 -0
  417. data/test/dummy/tmp/cache/sass/fbf85d5608ca3ac95eb64dfaa76546b623980b5f/_hover-link.scssc +0 -0
  418. data/test/dummy/tmp/cache/sass/fbf85d5608ca3ac95eb64dfaa76546b623980b5f/_link-colors.scssc +0 -0
  419. data/test/dummy/tmp/cache/sass/fbf85d5608ca3ac95eb64dfaa76546b623980b5f/_unstyled-link.scssc +0 -0
  420. data/test/dummy/tmp/cache/sass/fcfbf62c4a5c26b3ae30accefa73ef6191bb4aab/_ellipsis.scssc +0 -0
  421. data/test/dummy/tmp/cache/sass/fcfbf62c4a5c26b3ae30accefa73ef6191bb4aab/_force-wrap.scssc +0 -0
  422. data/test/dummy/tmp/cache/sass/fcfbf62c4a5c26b3ae30accefa73ef6191bb4aab/_nowrap.scssc +0 -0
  423. data/test/dummy/tmp/cache/sass/fcfbf62c4a5c26b3ae30accefa73ef6191bb4aab/_replacement.scssc +0 -0
  424. data/test/fixtures/lentil/admin_users.yml +35 -0
  425. data/test/fixtures/lentil/battles.yml +20 -0
  426. data/test/fixtures/lentil/flags.yml +17 -0
  427. data/test/fixtures/lentil/images.yml +284 -0
  428. data/test/fixtures/lentil/licenses.yml +25 -0
  429. data/test/fixtures/lentil/licensings.yml +20 -0
  430. data/test/fixtures/lentil/like_votes.yml +19 -0
  431. data/test/fixtures/lentil/services.yml +20 -0
  432. data/test/fixtures/lentil/taggings.yml +29 -0
  433. data/test/fixtures/lentil/tags.yml +29 -0
  434. data/test/fixtures/lentil/tagset_assignments.yml +28 -0
  435. data/test/fixtures/lentil/tagsets.yml +27 -0
  436. data/test/fixtures/lentil/users.yml +40 -0
  437. data/test/functional/admin/flags_controller_test.rb +16 -0
  438. data/test/functional/admin/images_controller_test.rb +46 -0
  439. data/test/functional/admin/tags_controller_test.rb +16 -0
  440. data/test/functional/admin/tagsets_controller_test.rb +21 -0
  441. data/test/functional/admin/users_controller_test.rb +16 -0
  442. data/test/functional/lentil/flags_controller_test.rb +19 -0
  443. data/test/functional/lentil/images_controller_test.rb +51 -0
  444. data/test/functional/lentil/like_votes_controller_test.rb +19 -0
  445. data/test/functional/lentil/photographers_controller_test.rb +14 -0
  446. data/test/functional/lentil/thisorthat_controller_test.rb +9 -0
  447. data/test/integration/lentil/admin_dashboard_test.rb +31 -0
  448. data/test/integration/lentil/admin_moderation_test.rb +9 -0
  449. data/test/integration/lentil/admin_tagset_test.rb +14 -0
  450. data/test/integration/lentil/images_feed_test.rb +14 -0
  451. data/test/integration/lentil/images_index_test.rb +46 -0
  452. data/test/integration/lentil/images_show_test.rb +14 -0
  453. data/test/integration/lentil/javascript/event_tracking_battle_test.rb +18 -0
  454. data/test/integration/lentil/javascript/event_tracking_test.rb +67 -0
  455. data/test/integration/lentil/javascript/image_modal_test.rb +20 -0
  456. data/test/integration/lentil/navigation_test.rb +10 -0
  457. data/test/integration/lentil/pages_test.rb +11 -0
  458. data/test/integration/lentil/thisorthat_test.rb +33 -0
  459. data/test/lentil_test.rb +7 -0
  460. data/test/test_helper.rb +79 -0
  461. data/test/unit/lentil/admin_user_test.rb +26 -0
  462. data/test/unit/lentil/battle_test.rb +18 -0
  463. data/test/unit/lentil/flag_test.rb +17 -0
  464. data/test/unit/lentil/helpers/images_helper_test.rb +4 -0
  465. data/test/unit/lentil/helpers/photographers_helper_test.rb +4 -0
  466. data/test/unit/lentil/helpers/thisorthat_helper_test.rb +4 -0
  467. data/test/unit/lentil/image_test.rb +52 -0
  468. data/test/unit/lentil/instagram_test.rb +57 -0
  469. data/test/unit/lentil/license_test.rb +20 -0
  470. data/test/unit/lentil/licensing_test.rb +18 -0
  471. data/test/unit/lentil/like_vote_test.rb +17 -0
  472. data/test/unit/lentil/popularity_test.rb +19 -0
  473. data/test/unit/lentil/service_test.rb +18 -0
  474. data/test/unit/lentil/tag_test.rb +21 -0
  475. data/test/unit/lentil/tagging_test.rb +19 -0
  476. data/test/unit/lentil/tagset_assignment_test.rb +18 -0
  477. data/test/unit/lentil/tagset_test.rb +22 -0
  478. data/test/unit/lentil/user_test.rb +37 -0
  479. data/test/vcr_cassettes/battle_images.yml +245 -0
  480. data/test/vcr_cassettes/battle_images_events.yml +206 -0
  481. data/test/vcr_cassettes/instagram_bad_image_check.yml +40 -0
  482. data/test/vcr_cassettes/instagram_by_tag.yml +318 -0
  483. data/test/vcr_cassettes/instagram_good_image_check.yml +42 -0
  484. data/test/vcr_cassettes/instagram_image_harvest.yml +1992 -0
  485. data/test/vcr_cassettes/instagram_image_id.yml +97 -0
  486. data/test/vcr_cassettes/instagram_oembed.yml +43 -0
  487. data/vendor/assets/javascripts/animatedimages/css/demo.css +178 -0
  488. data/vendor/assets/javascripts/animatedimages/css/fallback.css +12 -0
  489. data/vendor/assets/javascripts/animatedimages/css/style.css +132 -0
  490. data/vendor/assets/javascripts/animatedimages/images/Thumbs.db +0 -0
  491. data/vendor/assets/javascripts/animatedimages/images/bg.jpg +0 -0
  492. data/vendor/assets/javascripts/animatedimages/images/light.png +0 -0
  493. data/vendor/assets/javascripts/animatedimages/images/loading.gif +0 -0
  494. data/vendor/assets/javascripts/animatedimages/js/jquery.gridrotator.js +760 -0
  495. data/vendor/assets/javascripts/animatedimages/js/modernizr.custom.26633.js +4 -0
  496. data/vendor/assets/javascripts/expanding/expanding.js +118 -0
  497. data/vendor/assets/javascripts/html5historyapi/README.md +338 -0
  498. data/vendor/assets/javascripts/html5historyapi/component.json +8 -0
  499. data/vendor/assets/javascripts/html5historyapi/history.iegte8.js +721 -0
  500. data/vendor/assets/javascripts/html5historyapi/history.iegte8.min.js +30 -0
  501. data/vendor/assets/javascripts/html5historyapi/history.js +890 -0
  502. data/vendor/assets/javascripts/html5historyapi/history.min.js +33 -0
  503. data/vendor/assets/javascripts/html5historyapi/readme.en.txt +161 -0
  504. data/vendor/assets/javascripts/html5historyapi/readme.ru.txt +161 -0
  505. data/vendor/assets/javascripts/imagesloaded/jquery.imagesloaded.min.js +3 -0
  506. data/vendor/assets/javascripts/infinitescroll/Readme.md +59 -0
  507. data/vendor/assets/javascripts/infinitescroll/ajax-loader.gif +0 -0
  508. data/vendor/assets/javascripts/infinitescroll/behaviors/cufon.js +21 -0
  509. data/vendor/assets/javascripts/infinitescroll/behaviors/local.js +26 -0
  510. data/vendor/assets/javascripts/infinitescroll/behaviors/manual-trigger.js +59 -0
  511. data/vendor/assets/javascripts/infinitescroll/behaviors/masonry-isotope.js +21 -0
  512. data/vendor/assets/javascripts/infinitescroll/behaviors/sausage.js +19 -0
  513. data/vendor/assets/javascripts/infinitescroll/jquery.infinitescroll.js +802 -0
  514. data/vendor/assets/javascripts/infinitescroll/package.json +7 -0
  515. data/vendor/assets/javascripts/infinitescroll/site/assets/anivers_regular.otf +0 -0
  516. data/vendor/assets/javascripts/infinitescroll/site/assets/buttons.psd +0 -0
  517. data/vendor/assets/javascripts/infinitescroll/site/assets/logo.psd +0 -0
  518. data/vendor/assets/javascripts/infinitescroll/site/assets/mobius-strip2.ai +2266 -15
  519. data/vendor/assets/javascripts/infinitescroll/site/assets/pattern.psd +0 -0
  520. data/vendor/assets/javascripts/infinitescroll/site/assets/selector spots.psd +0 -0
  521. data/vendor/assets/javascripts/infinitescroll/site/assets/sites.psd +0 -0
  522. data/vendor/assets/javascripts/infinitescroll/site/buttons.png +0 -0
  523. data/vendor/assets/javascripts/infinitescroll/site/infinite-scroll-pattern.gif +0 -0
  524. data/vendor/assets/javascripts/infinitescroll/site/logo.jpg +0 -0
  525. data/vendor/assets/javascripts/infinitescroll/site/screens.jpg +0 -0
  526. data/vendor/assets/javascripts/infinitescroll/site/selectors.jpg +0 -0
  527. data/vendor/assets/javascripts/infinitescroll/test/debug.js +24 -0
  528. data/vendor/assets/javascripts/infinitescroll/test/index.html +105 -0
  529. data/vendor/assets/javascripts/infinitescroll/test/index2.html +41 -0
  530. data/vendor/assets/javascripts/infinitescroll/test/index3.html +48 -0
  531. data/vendor/assets/javascripts/infinitescroll/test/jquery-1.6.1.js +8936 -0
  532. data/vendor/assets/javascripts/infinitescroll/test/mobile.html +108 -0
  533. data/vendor/assets/javascripts/infinitescroll/test/mobile2.json +1 -0
  534. data/vendor/assets/javascripts/infinitescroll/test/mobile3.json +1 -0
  535. data/vendor/assets/javascripts/infinitescroll/test/mobile4.json +1 -0
  536. data/vendor/assets/javascripts/infinitescroll/test/style.css +319 -0
  537. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/img/ajax-loader.gif +0 -0
  538. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/includes/admin.php +126 -0
  539. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/includes/options.php +188 -0
  540. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/includes/presets.php +737 -0
  541. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/includes/submit.php +67 -0
  542. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/infinite-scroll.php +261 -0
  543. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/js/admin/infinite-scoll.js +5 -0
  544. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/js/admin/infinite-scroll.dev.js +128 -0
  545. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/js/front-end/jquery.infinitescroll.dev.js +747 -0
  546. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/js/front-end/jquery.infinitescroll.js +31 -0
  547. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/languages/infinite-scroll.pot +157 -0
  548. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/license.html +694 -0
  549. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/readme.md +246 -0
  550. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/readme.txt +241 -0
  551. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/screenshot-1.png +0 -0
  552. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/screenshot-2.png +0 -0
  553. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/screenshot-3.png +0 -0
  554. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/footer.php +7 -0
  555. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/manage-presets.php +21 -0
  556. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/options.php +97 -0
  557. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/preset-prompt.php +7 -0
  558. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/submit-prompt.php +23 -0
  559. data/vendor/assets/javascripts/infinitescroll/wordpress-plugin/templates/submit.php +31 -0
  560. data/vendor/assets/javascripts/spin/spin.js +2 -0
  561. data/vendor/assets/javascripts/touchswipe/README.md +84 -0
  562. data/vendor/assets/javascripts/touchswipe/jquery.touchSwipe.js +1555 -0
  563. metadata +1397 -0
@@ -0,0 +1,7 @@
1
+ <?php
2
+ /**
3
+ * Template to include on wp_footer front-end; passes plugin options to javascript function
4
+ * @package Infinite_Scroll
5
+ */
6
+ ?>
7
+ <script>jQuery( infinite_scroll.contentSelector ).infinitescroll( infinite_scroll );</script>
@@ -0,0 +1,21 @@
1
+ <?php
2
+ /**
3
+ * Template for manage presets page
4
+ * @package Infinite_Scroll
5
+ * @uses Infinite_Scroll_Presets_Table
6
+ */
7
+
8
+ if ( is_multisite() && !is_super_admin() )
9
+ wp_die( 'Not authorized', 'infinite-scroll' );
10
+
11
+ $table = new Infinite_Scroll_Presets_Table();
12
+ $table->prepare_items();
13
+ ?>
14
+ <div class="wrap">
15
+ <h2><?php _e( 'Mange Infinite Scroll Presets', 'infinite-scroll' ); ?></h2>
16
+ <p class="description"><?php _e( 'Many theme\'s CSS selector\'s are stored in a community contributed database maintained by the plugin. If the current theme\'s CSS selectors are known, the plugin will automatically use them if the site administrator has not set any. This list will update automatically as additional theme\'s are added. You can add to and/or override those community defaults below. Changes entered here will affect only your site on a single-site install, and only your network\'s site on a multisite install.', 'infinite-scroll' ); ?></p>
17
+ <form id="ajax-form">
18
+ <?php $table->display(); ?>
19
+ <div style="margin-top: -2em;"><a href="<?php echo admin_url( 'options-general.php?page=infinite_scroll_options'); ?>"><?php _e( 'Back to General Options', 'infinite-scroll' ); ?></a> | <a href="<?php echo esc_url( add_query_arg( 'submit', true ) ); ?>"><?php _e( 'Export/Submit', 'infinite-scroll' ); ?></a></div>
20
+ </div>
21
+ </form>
@@ -0,0 +1,97 @@
1
+ <?php
2
+ /**
3
+ * Template to display options page
4
+ * @package Infinite_Scroll
5
+ */
6
+ ?>
7
+ <div class="wrap">
8
+ <h2><?php _e( 'Infinite Scroll Options', 'infinite-scroll' ); ?></h2>
9
+ <form method="post" action="options.php" id="infinite_scroll_form">
10
+ <?php settings_errors(); ?>
11
+ <?php settings_fields( $this->parent->slug_ ); ?>
12
+ <p class="description"><?php _e( 'Infinite scroll uses <a href="http://www.w3.org/TR/CSS2/selector.html">CSS selectors</a> to identify various parts of your site\'s unique theme. In most cases, identifying each of your theme\'s elements below simply requires entering either the element\'s ID indicated with a hashmark, (<em>e.g.,</em><code>#content</code>), or the element\'s class indicated by a period, (<em>e.g.,</em><code>.post</code>). For more information, please see <a href="http://docs.jquery.com/Selectors">jQuery\'s CSS Selector documentation</a>.', 'infinite-scroll' ); ?></p>
13
+ <?php $this->parent->presets->preset_prompt(); ?>
14
+ <table class="form-table">
15
+ <tr valign="top">
16
+ <th scope="row">
17
+ <?php _e( 'Content Selector', 'infinite-scroll' ); ?>
18
+ </th>
19
+ <td>
20
+ <input type="text" name="infinite_scroll[contentSelector]" id="infinite_scroll[contentSelector]" value="<?php echo esc_attr( $this->parent->options->contentSelector ); ?>" class="regular-text" /><br />
21
+ <span class="description"><?php _e( 'Div containing your theme\'s content', 'infinite-scroll' ); ?></span>
22
+ </td>
23
+ </tr>
24
+ <tr valign="top">
25
+ <th scope="row">
26
+ <?php _e( 'Navigation Selector', 'infinite-scroll' ); ?>
27
+ </th>
28
+ <td>
29
+ <input type="text" name="infinite_scroll[navSelector]" id="infinite_scroll[navSelector]" value="<?php echo esc_attr( $this->parent->options->navSelector ); ?>" class="regular-text" /><br />
30
+ <span class="description"><?php _e( 'Div containing your theme\'s navigation', 'infinite-scroll' ); ?></span>
31
+ </td>
32
+ </tr>
33
+ <tr valign="top">
34
+ <th scope="row">
35
+ <?php _e( 'Next Selector', 'infinite-scroll' ); ?>
36
+ </th>
37
+ <td>
38
+ <input type="text" name="infinite_scroll[nextSelector]" id="infinite_scroll[nextSelector]" value="<?php echo esc_attr( $this->parent->options->nextSelector ); ?>" class="regular-text" /><br />
39
+ <span class="description"><?php _e( 'Link to next page of content', 'infinite-scroll' ); ?></span>
40
+ </td>
41
+ </tr>
42
+ <tr valign="top">
43
+ <th scope="row">
44
+ <?php _e( 'Item Selector', 'infinite-scroll' ); ?>
45
+ </th>
46
+ <td>
47
+ <input type="text" name="infinite_scroll[itemSelector]" id="infinite_scroll[itemSelector]" value="<?php echo esc_attr( $this->parent->options->itemSelector ); ?>" class="regular-text" /><br />
48
+ <span class="description"><?php _e( 'Div containing an individual post', 'infinite-scroll' ); ?></span>
49
+ </td>
50
+ </tr>
51
+ <?php $this->parent->submit->prompt(); ?>
52
+ <tr valign="top">
53
+ <th scope="row">
54
+ <?php _e( 'Loading Message', 'infinite-scroll' ); ?>
55
+ </th>
56
+ <td>
57
+ <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
58
+ <?php $this->parent->admin->editor( 'msgText' ); ?>
59
+ <span class="description"><?php _e( 'Text to display as new posts are retrieved', 'infinite-scroll' ); ?></span>
60
+ </div>
61
+ </td>
62
+ </tr>
63
+ <tr valign="top">
64
+ <th scope="row">
65
+ <?php _e( 'Finished Message', 'infinite-scroll' ); ?>
66
+ </th>
67
+ <td>
68
+ <div id="<?php echo user_can_richedit() ? 'postdivrich' : 'postdiv'; ?>" class="postarea">
69
+ <?php $this->parent->admin->editor( 'finishedMsg' ); ?>
70
+ <span class="description"><?php _e( 'Text to display when no additional posts are available', 'infinite-scroll' ); ?></span>
71
+ </div>
72
+ </td>
73
+ </tr>
74
+ <tr valign="top">
75
+ <th scope="row">
76
+ <?php _e( 'Loading Image', 'infinite-scroll' ); ?>
77
+ </th>
78
+ <td>
79
+ <?php _e( 'Current Image:', 'infinite-scroll' ); ?> <img src="<?php echo esc_attr( $this->parent->options->img ); ?>" alt="<?php _e( 'Current Loading Image', 'infinite-scroll' ); ?>" /><br />
80
+ <?php _e( 'New Image:', 'infinite-scroll' ); ?>
81
+ <input id="upload_image" type="text" size="36" name="infinite_scroll[img]" value="" />
82
+ <input id="upload_image_button" type="button" value="<?php _e( 'Upload New Image', 'infinite-scroll' ); ?>" /> <?php if ( $this->parent->options->img != $this->parent->options->defaults['img'] ) { ?>
83
+ ( <a href="#" id="use_default"><?php _e( 'Use Default', 'infinite-scroll' ); ?></a> )
84
+ <?php } ?>
85
+ <br />
86
+ <span class="description"><?php _e( 'URL of existing or uploaded image to display as new posts are retrieved', 'infinite-scroll' ); ?></span>
87
+ </td>
88
+ </tr>
89
+ </table>
90
+ <p class="submit">
91
+ <input type="submit" class="button-primary" value="<?php _e( 'Save Options', 'infinite-scroll' ); ?>" />
92
+ </p>
93
+ <?php if ( !is_multisite() || is_super_admin() ) { ?>
94
+ <div style="float:right; margin-top: -50px; margin-right:20px;"><a href="<?php echo esc_url( add_query_arg( 'manage-presets', true ) ); ?>"><?php _e( 'Manage Defaults'); ?></a></div>
95
+ <?php } ?>
96
+ </form>
97
+ </div>
@@ -0,0 +1,7 @@
1
+ <?php
2
+ /**
3
+ * Prompt to display when plugin knows theme defaults but user has not chosen
4
+ * @package Infinite_Scroll
5
+ */
6
+ ?>
7
+ <p><?php echo sprintf( __( 'Other users have submitted default CSS selectors for your theme. Would you like to <strong><a href="%s">use your theme\'s default selectors</a></strong>?'), esc_url( add_query_arg( 'nonce', wp_create_nonce( 'infinite-scroll-presets' ), add_query_arg( 'set_presets', true ) ) ) ); ?></p>
@@ -0,0 +1,23 @@
1
+ <?php
2
+ /**
3
+ * Prompt to display when we want user to submit CSS Selectors to community database
4
+ * @package Infinite_Scroll
5
+ */
6
+ ?>
7
+ <tr id="submit" valign="top">
8
+ <th>&nbsp;</th>
9
+ <td>
10
+ <p class="description"><?php echo sprintf( __( 'Please consider <a href="%s">submitting your theme\'s CSS selectors</a> to the global CSS selector database to make installation and configuration easier for other users', 'infinite-scroll'), esc_url( add_query_arg( 'submit', true ) ) ); ?>
11
+
12
+ <span style="font-size: 10px;">
13
+ (<a href="#" id="hide-submit"><?php _e( 'hide this message' ); ?></a>)
14
+ </span>
15
+ </p>
16
+ <?php wp_nonce_field( $this->parent->slug_ . '_hide_submit' , '_ajax_nonce-' . $this->parent->slug . '-hide-submit' ); ?>
17
+
18
+ <?php $data = array( 'action' => $this->parent->slug_ . '_hide_submit', 'nonce' => '_ajax_nonce-' . $this->parent->slug . '-hide-submit' ); ?>
19
+
20
+ <script>var submit = <?php echo json_encode( $data ); ?>;</script>
21
+
22
+ </td>
23
+ </div>
@@ -0,0 +1,31 @@
1
+ <?php
2
+ /**
3
+ * Outputs CSV of custom selecors and provides instructions on how to submit
4
+ * @package Infinite_Scroll
5
+ */
6
+ ?>
7
+ <div class="wrap">
8
+ <h2><?php _e( 'Submit CSS Selectors' ); ?></h2>
9
+ <p class="description"><?php _e( 'Infinite Scroll maintains a global database of CSS selectors to help new users, and users without knowledge of CSS selectors adapt the plugin to fit their individual theme. If you have enjoyed this free plugin, please consider contributing back to the community by taking a moment to submit the below information.', 'infinite-scroll' ); ?></p>
10
+ <strong><?php _e( 'How to submit:', 'infinite-scroll' ); ?></strong>
11
+ <ol>
12
+ <li><?php _e( 'Press <code>CTRL-C</code> (PC) or <code>Command-C</code> (Mac) to copy the below CSS selectors to your computer\'s clipboard.', 'infinite-scroll' );?></li>
13
+ <li><?php echo sprintf( __( 'Navigate to the <a href="%s" target="_BLANK">Infinite Scroll Support Forum CSS Selectors Page</a>, and if you don\'t already have one, <a href="%s" target="_BLANK">create a WordPress.org account</a> (it takes 30 seconds!).', 'infinite-scroll'), $this->parent->submit->url, 'http://wordpress.org/support/register.php' );?></li>
14
+ <li><?php _e( 'Click the reply message box (the big input area)', 'infinite-scroll' ); ?></li>
15
+ <li><?php _e( 'Press <code>CTRL-V</code> (PC) or <code>Command-V</code> (Mac) to paste the selectors into the message box', 'infinite-scroll' ); ?></li>
16
+ <li><?php _e( 'Add a message, if you\'d like (optional)', 'infinit-scroll' ); ?></li>
17
+ <li><?php _e( 'Click "<code>Post</code>"', 'infinite-scroll' ); ?></li>
18
+ </ol>
19
+ <strong><?php echo ( isset( $_GET['all'] ) ) ? __( 'All CSS Selectors:', 'infinite-scroll' ) : __( 'Your CSS Selectors:', 'infinite-scroll' ); ?></strong>
20
+ <textarea style="width: 100%; height: 200px;" id="submit">
21
+ &lt;blockquote>
22
+ <?php echo $this->parent->presets->export( isset( $_GET['all'] ) ); ?>
23
+ &lt;/blockquote></textarea>
24
+ <span style="font-size: 10px;">
25
+ <?php if ( isset( $_GET['all'] ) ) { ?>
26
+ <a href="<?php echo esc_url( remove_query_arg( 'all' ) ); ?>"><?php _e( 'Export only custom selectors' ); ?></a>
27
+ <?php } else { ?>
28
+ <a href="<?php echo esc_url( add_query_arg( 'all', true ) ); ?>"><?php _e( 'Export all selectors' ); ?></a>
29
+ <?php } ?>
30
+ </span>
31
+ </div>
@@ -0,0 +1,2 @@
1
+ //fgnass.github.com/spin.js#v1.2.7
2
+ !function(e,t,n){function o(e,n){var r=t.createElement(e||"div"),i;for(i in n)r[i]=n[i];return r}function u(e){for(var t=1,n=arguments.length;t<n;t++)e.appendChild(arguments[t]);return e}function f(e,t,n,r){var o=["opacity",t,~~(e*100),n,r].join("-"),u=.01+n/r*100,f=Math.max(1-(1-e)/t*(100-u),e),l=s.substring(0,s.indexOf("Animation")).toLowerCase(),c=l&&"-"+l+"-"||"";return i[o]||(a.insertRule("@"+c+"keyframes "+o+"{"+"0%{opacity:"+f+"}"+u+"%{opacity:"+e+"}"+(u+.01)+"%{opacity:1}"+(u+t)%100+"%{opacity:"+e+"}"+"100%{opacity:"+f+"}"+"}",a.cssRules.length),i[o]=1),o}function l(e,t){var i=e.style,s,o;if(i[t]!==n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(o=0;o<r.length;o++){s=r[o]+t;if(i[s]!==n)return s}}function c(e,t){for(var n in t)e.style[l(e,n)||n]=t[n];return e}function h(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var i in r)e[i]===n&&(e[i]=r[i])}return e}function p(e){var t={x:e.offsetLeft,y:e.offsetTop};while(e=e.offsetParent)t.x+=e.offsetLeft,t.y+=e.offsetTop;return t}var r=["webkit","Moz","ms","O"],i={},s,a=function(){var e=o("style",{type:"text/css"});return u(t.getElementsByTagName("head")[0],e),e.sheet||e.styleSheet}(),d={lines:12,length:7,width:5,radius:10,rotate:0,corners:1,color:"#000",speed:1,trail:100,opacity:.25,fps:20,zIndex:2e9,className:"spinner",top:"auto",left:"auto",position:"relative"},v=function m(e){if(!this.spin)return new m(e);this.opts=h(e||{},m.defaults,d)};v.defaults={},h(v.prototype,{spin:function(e){this.stop();var t=this,n=t.opts,r=t.el=c(o(0,{className:n.className}),{position:n.position,width:0,zIndex:n.zIndex}),i=n.radius+n.length+n.width,u,a;e&&(e.insertBefore(r,e.firstChild||null),a=p(e),u=p(r),c(r,{left:(n.left=="auto"?a.x-u.x+(e.offsetWidth>>1):parseInt(n.left,10)+i)+"px",top:(n.top=="auto"?a.y-u.y+(e.offsetHeight>>1):parseInt(n.top,10)+i)+"px"})),r.setAttribute("aria-role","progressbar"),t.lines(r,t.opts);if(!s){var f=0,l=n.fps,h=l/n.speed,d=(1-n.opacity)/(h*n.trail/100),v=h/n.lines;(function m(){f++;for(var e=n.lines;e;e--){var i=Math.max(1-(f+e*v)%h*d,n.opacity);t.opacity(r,n.lines-e,i,n)}t.timeout=t.el&&setTimeout(m,~~(1e3/l))})()}return t},stop:function(){var e=this.el;return e&&(clearTimeout(this.timeout),e.parentNode&&e.parentNode.removeChild(e),this.el=n),this},lines:function(e,t){function i(e,r){return c(o(),{position:"absolute",width:t.length+t.width+"px",height:t.width+"px",background:e,boxShadow:r,transformOrigin:"left",transform:"rotate("+~~(360/t.lines*n+t.rotate)+"deg) translate("+t.radius+"px"+",0)",borderRadius:(t.corners*t.width>>1)+"px"})}var n=0,r;for(;n<t.lines;n++)r=c(o(),{position:"absolute",top:1+~(t.width/2)+"px",transform:t.hwaccel?"translate3d(0,0,0)":"",opacity:t.opacity,animation:s&&f(t.opacity,t.trail,n,t.lines)+" "+1/t.speed+"s linear infinite"}),t.shadow&&u(r,c(i("#000","0 0 4px #000"),{top:"2px"})),u(e,u(r,i(t.color,"0 0 1px rgba(0,0,0,.1)")));return e},opacity:function(e,t,n){t<e.childNodes.length&&(e.childNodes[t].style.opacity=n)}}),function(){function e(e,t){return o("<"+e+' xmlns="urn:schemas-microsoft.com:vml" class="spin-vml">',t)}var t=c(o("group"),{behavior:"url(#default#VML)"});!l(t,"transform")&&t.adj?(a.addRule(".spin-vml","behavior:url(#default#VML)"),v.prototype.lines=function(t,n){function s(){return c(e("group",{coordsize:i+" "+i,coordorigin:-r+" "+ -r}),{width:i,height:i})}function l(t,i,o){u(a,u(c(s(),{rotation:360/n.lines*t+"deg",left:~~i}),u(c(e("roundrect",{arcsize:n.corners}),{width:r,height:n.width,left:n.radius,top:-n.width>>1,filter:o}),e("fill",{color:n.color,opacity:n.opacity}),e("stroke",{opacity:0}))))}var r=n.length+n.width,i=2*r,o=-(n.width+n.length)*2+"px",a=c(s(),{position:"absolute",top:o,left:o}),f;if(n.shadow)for(f=1;f<=n.lines;f++)l(f,-2,"progid:DXImageTransform.Microsoft.Blur(pixelradius=2,makeshadow=1,shadowopacity=.3)");for(f=1;f<=n.lines;f++)l(f);return u(t,a)},v.prototype.opacity=function(e,t,n,r){var i=e.firstChild;r=r.shadow&&r.lines||0,i&&t+r<i.childNodes.length&&(i=i.childNodes[t+r],i=i&&i.firstChild,i=i&&i.firstChild,i&&(i.opacity=n))}):s=l(t,"animation")}(),typeof define=="function"&&define.amd?define(function(){return v}):e.Spinner=v}(window,document);
@@ -0,0 +1,84 @@
1
+ #TouchSwipe 1.6
2
+ A jquery plugin to be used on touch devices such as iPad, iPhone, android etc
3
+
4
+ Detects single and multiple finger swipes, pinches and falls back to mouse 'drags' on the desktop.
5
+
6
+ Time and distance thresholds can be set to destinguish between swipe gesture and slow drag.
7
+
8
+ Allows exclusion of child elements (interactive elements) as well allowing page scrolling or page zooming depending on configuration.
9
+
10
+
11
+ ### Demos, examples and docs
12
+
13
+ [http://labs.skinkers.com/touchSwipe](http://labs.skinkers.com/touchSwipe)
14
+
15
+ [http://labs.skinkers.com/touchSwipe/demo](http://labs.skinkers.com/touchSwipe/demo)
16
+
17
+ [http://labs.skinkers.com/touchSwipe/docs](http://labs.skinkers.com/touchSwipe/docs)
18
+
19
+
20
+
21
+ ### For port to XUI see:
22
+ https://github.com/cowgp/xui-touchSwipe
23
+
24
+ ### Version History
25
+
26
+
27
+ * **1.6.0** *2013-01-12*
28
+ - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture.
29
+ - made the demo site all static local HTML pages so they can be run locally by a developer
30
+ - added jsDoc comments and added documentation for the plugin
31
+ - code tidy
32
+ - added triggerOnTouchLeave property that will end the event when the user swipes off the element.
33
+
34
+
35
+ * **1.5.1** *2012-11-22*
36
+ - Fixed bug with jQuery 1.8 and trailing comma in excludedElements
37
+ - Fixed bug with IE and event.preventDefault();
38
+ * **1.5.0** *2012-11-10*
39
+ - Added `excludedElements`, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements.
40
+ * **1.4.0** *2012-04-10*
41
+ - Added pinch support, `pinchIn`, `pinchOut` and `pinchStatus`
42
+ * **1.3.3** *2012-09-08*
43
+ - Code tidy prep for minified version
44
+ * **1.3.2** *2012-29-07*
45
+ - Added `fallbackToMouseEvents` option to NOT capture mouse events on non touch devices.
46
+ - Added "all" fingers value to the fingers property, so any combinatin of fingers triggers the swipe, allowing event handlers to check the finger count
47
+ * **1.3.1** *2012-05-06*
48
+ - Bug fixes
49
+ - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly.
50
+ * **1.3.0** *2012-06-06*
51
+ - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added `enable`, `disable`, and `destroy` methods
52
+ * **1.2.8** *2012-05-06*
53
+ - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event.
54
+ * **1.2.7** *2012-05-06*
55
+ - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled.
56
+ * **1.2.6** *2012-14-05*
57
+ - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected
58
+ * **1.2.5** *2011-27-09*
59
+ - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy)
60
+ * **1.2.4** *2011-28-04*
61
+ - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring.
62
+ * **1.2.2** *2011-23-02*
63
+ - Fixed bug where scope was not preserved in callback methods.
64
+ * **1.2.1** *2011-23-02*
65
+ - removed console log!
66
+ * **1.2.0** *2011-23-02*
67
+ - added `click` handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler.
68
+ - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
69
+ * **1.1.0** *2011-21-02*
70
+ - added `allowPageScroll` property to allow swiping and scrolling of page
71
+ - changed handler signatures so one handler can be used for multiple events
72
+ * **1.0.1** *2010-12-12*
73
+ - removed multibyte comments
74
+ * **1.0.0** *2010-12-12*
75
+ - feature complete
76
+
77
+
78
+
79
+
80
+
81
+
82
+
83
+
84
+
@@ -0,0 +1,1555 @@
1
+ /*
2
+ * @fileOverview TouchSwipe - jQuery Plugin
3
+ * @version 1.6.0
4
+ *
5
+ * @author Matt Bryson http://www.github.com/mattbryson
6
+ * @see https://github.com/mattbryson/TouchSwipe-Jquery-Plugin
7
+ * @see http://labs.skinkers.com/touchSwipe/
8
+ * @see http://plugins.jquery.com/project/touchSwipe
9
+ *
10
+ * Copyright (c) 2010 Matt Bryson (www.skinkers.com)
11
+ * Dual licensed under the MIT or GPL Version 2 licenses.
12
+ *
13
+ *
14
+ * Changelog
15
+ * $Date: 2010-12-12 (Wed, 12 Dec 2010) $
16
+ * $version: 1.0.0
17
+ * $version: 1.0.1 - removed multibyte comments
18
+ *
19
+ * $Date: 2011-21-02 (Mon, 21 Feb 2011) $
20
+ * $version: 1.1.0 - added allowPageScroll property to allow swiping and scrolling of page
21
+ * - changed handler signatures so one handler can be used for multiple events
22
+ * $Date: 2011-23-02 (Wed, 23 Feb 2011) $
23
+ * $version: 1.2.0 - added click handler. This is fired if the user simply clicks and does not swipe. The event object and click target are passed to handler.
24
+ * - If you use the http://code.google.com/p/jquery-ui-for-ipad-and-iphone/ plugin, you can also assign jQuery mouse events to children of a touchSwipe object.
25
+ * $version: 1.2.1 - removed console log!
26
+ *
27
+ * $version: 1.2.2 - Fixed bug where scope was not preserved in callback methods.
28
+ *
29
+ * $Date: 2011-28-04 (Thurs, 28 April 2011) $
30
+ * $version: 1.2.4 - Changed licence terms to be MIT or GPL inline with jQuery. Added check for support of touch events to stop non compatible browsers erroring.
31
+ *
32
+ * $Date: 2011-27-09 (Tues, 27 September 2011) $
33
+ * $version: 1.2.5 - Added support for testing swipes with mouse on desktop browser (thanks to https://github.com/joelhy)
34
+ *
35
+ * $Date: 2012-14-05 (Mon, 14 May 2012) $
36
+ * $version: 1.2.6 - Added timeThreshold between start and end touch, so user can ignore slow swipes (thanks to Mark Chase). Default is null, all swipes are detected
37
+ *
38
+ * $Date: 2012-05-06 (Tues, 05 June 2012) $
39
+ * $version: 1.2.7 - Changed time threshold to have null default for backwards compatibility. Added duration param passed back in events, and refactored how time is handled.
40
+ *
41
+ * $Date: 2012-05-06 (Tues, 05 June 2012) $
42
+ * $version: 1.2.8 - Added the possibility to return a value like null or false in the trigger callback. In that way we can control when the touch start/move should take effect or not (simply by returning in some cases return null; or return false;) This effects the ontouchstart/ontouchmove event.
43
+ *
44
+ * $Date: 2012-06-06 (Wed, 06 June 2012) $
45
+ * $version: 1.3.0 - Refactored whole plugin to allow for methods to be executed, as well as exposed defaults for user override. Added 'enable', 'disable', and 'destroy' methods
46
+ *
47
+ * $Date: 2012-05-06 (Fri, 05 June 2012) $
48
+ * $version: 1.3.1 - Bug fixes - bind() with false as last argument is no longer supported in jQuery 1.6, also, if you just click, the duration is now returned correctly.
49
+ *
50
+ * $Date: 2012-29-07 (Sun, 29 July 2012) $
51
+ * $version: 1.3.2 - Added fallbackToMouseEvents option to NOT capture mouse events on non touch devices.
52
+ * - Added "all" fingers value to the fingers property, so any combinatin of fingers triggers the swipe, allowing event handlers to check the finger count
53
+ *
54
+ * $Date: 2012-09-08 (Thurs, 9 Aug 2012) $
55
+ * $version: 1.3.3 - Code tidy prep for minified version
56
+ *
57
+ * $Date: 2012-04-10 (wed, 4 Oct 2012) $
58
+ * $version: 1.4.0 - Added pinch support, pinchIn and pinchOut
59
+ *
60
+ * $Date: 2012-11-10 (Thurs, 11 Oct 2012) $
61
+ * $version: 1.5.0 - Added excludedElements, a jquery selector that specifies child elements that do NOT trigger swipes. By default, this is one select that removes all form, input select, button and anchor elements.
62
+ *
63
+ * $Date: 2012-22-10 (Mon, 22 Oct 2012) $
64
+ * $version: 1.5.1 - Fixed bug with jQuery 1.8 and trailing comma in excludedElements
65
+ * - Fixed bug with IE and eventPreventDefault()
66
+ * $Date: 2013-01-12 (Fri, 12 Jan 2013) $
67
+ * $version: 1.6.0 - Fixed bugs with pinching, mainly when both pinch and swipe enabled, as well as adding time threshold for multifinger gestures, so releasing one finger beofre the other doesnt trigger as single finger gesture.
68
+ * - made the demo site all static local HTML pages so they can be run locally by a developer
69
+ * - added jsDoc comments and added documentation for the plugin
70
+ * - code tidy
71
+ * - added triggerOnTouchLeave property that will end the event when the user swipes off the element.
72
+ */
73
+
74
+ /**
75
+ * See (http://jquery.com/).
76
+ * @name $
77
+ * @class
78
+ * See the jQuery Library (http://jquery.com/) for full details. This just
79
+ * documents the function and classes that are added to jQuery by this plug-in.
80
+ */
81
+
82
+ /**
83
+ * See (http://jquery.com/)
84
+ * @name fn
85
+ * @class
86
+ * See the jQuery Library (http://jquery.com/) for full details. This just
87
+ * documents the function and classes that are added to jQuery by this plug-in.
88
+ * @memberOf $
89
+ */
90
+
91
+
92
+
93
+ (function ($) {
94
+ + "use strict";
95
+
96
+ //Constants
97
+ var LEFT = "left",
98
+ RIGHT = "right",
99
+ UP = "up",
100
+ DOWN = "down",
101
+ IN = "in",
102
+ OUT = "out",
103
+
104
+ NONE = "none",
105
+ AUTO = "auto",
106
+
107
+ SWIPE = "swipe",
108
+ PINCH = "pinch",
109
+ CLICK = "click",
110
+
111
+ HORIZONTAL = "horizontal",
112
+ VERTICAL = "vertical",
113
+
114
+ ALL_FINGERS = "all",
115
+
116
+ PHASE_START = "start",
117
+ PHASE_MOVE = "move",
118
+ PHASE_END = "end",
119
+ PHASE_CANCEL = "cancel",
120
+
121
+ SUPPORTS_TOUCH = 'ontouchstart' in window,
122
+
123
+ PLUGIN_NS = 'TouchSwipe';
124
+
125
+
126
+
127
+ /**
128
+ * The default configuration, and available options to configure touch swipe with.
129
+ * You can set the default values by updating any of the properties prior to instantiation.
130
+ * @name $.fn.swipe.defaults
131
+ * @namespace
132
+ * @property {int} [fingers=1] The number of fingers to detect in a swipe. Any swipes that do not meet this requirement will NOT trigger swipe handlers.
133
+ * @property {int} [threshold=75] The number of pixels that the user must move their finger by before it is considered a swipe.
134
+ * @property {int} [pinchThreshold=20] The number of pixels that the user must pinch their finger by before it is considered a pinch.
135
+ * @property {int} [maxTimeThreshold=null] Time, in milliseconds, between touchStart and touchEnd must NOT exceed in order to be considered a swipe.
136
+ * @property {int} [fingerReleaseThreshold=250] Time in milliseconds between releasing multiple fingers. If 2 fingers are down, and are released one after the other, if they are within this threshold, it counts as a simultaneous release.
137
+ * @property {function} [swipe=null] A handler to catch all swipes. See {@link $.fn.swipe#event:swipe}
138
+ * @property {function} [swipeLeft=null] A handler that is triggered for "left" swipes. See {@link $.fn.swipe#event:swipeLeft}
139
+ * @property {function} [swipeRight=null] A handler that is triggered for "right" swipes. See {@link $.fn.swipe#event:swipeRight}
140
+ * @property {function} [swipeUp=null] A handler that is triggered for "up" swipes. See {@link $.fn.swipe#event:swipeUp}
141
+ * @property {function} [swipeDown=null] A handler that is triggered for "down" swipes. See {@link $.fn.swipe#event:swipeDown}
142
+ * @property {function} [swipeStatus=null] A handler triggered for every phase of the swipe. See {@link $.fn.swipe#event:swipeStatus}
143
+ * @property {function} [pinchIn=null] A handler triggered for pinch in events. See {@link $.fn.swipe#event:pinchIn}
144
+ * @property {function} [pinchOut=null] A handler triggered for pinch out events. See {@link $.fn.swipe#event:pinchOut}
145
+ * @property {function} [pinchStatus=null] A handler triggered for every phase of a pinch. See {@link $.fn.swipe#event:pinchStatus}
146
+ * @property {function} [click=null] A handler triggered when a user just clicks on the item, rather than swipes it. If they do not move, click is triggered, if they do move, it is not.
147
+ * @property {boolean} [triggerOnTouchEnd=true] If true, the swipe events are triggered when the touch end event is received (user releases finger). If false, it will be triggered on reaching the threshold, and then cancel the touch event automatically.
148
+ * @property {boolean} [triggerOnTouchLeave=false] If true, then when the user leaves the swipe object, the swipe will end and trigger appropriate handlers.
149
+ * @property {string} [allowPageScroll='auto'] How the browser handles page scrolls when the user is swiping on a touchSwipe object. See {@link $.fn.swipe.pageScroll}. <br/><br/>
150
+ <code>"auto"</code> : all undefined swipes will cause the page to scroll in that direction. <br/>
151
+ <code>"none"</code> : the page will not scroll when user swipes. <br/>
152
+ <code>"horizontal"</code> : will force page to scroll on horizontal swipes. <br/>
153
+ <code>"vertical"</code> : will force page to scroll on vertical swipes. <br/>
154
+ * @property {boolean} [fallbackToMouseEvents=true] If true mouse events are used when run on a non touch device, false will stop swipes being triggered by mouse events on non tocuh devices.
155
+ * @property {string} [excludedElements="button, input, select, textarea, a, .noSwipe"] A jquery selector that specifies child elements that do NOT trigger swipes. By default this excludes all form, input, select, button, anchor and .noSwipe elements.
156
+
157
+ */
158
+ var defaults = {
159
+ fingers: 1,
160
+ threshold: 75,
161
+ pinchThreshold:20,
162
+ maxTimeThreshold: null,
163
+ fingerReleaseThreshold:250,
164
+ swipe: null,
165
+ swipeLeft: null,
166
+ swipeRight: null,
167
+ swipeUp: null,
168
+ swipeDown: null,
169
+ swipeStatus: null,
170
+ pinchIn:null,
171
+ pinchOut:null,
172
+ pinchStatus:null,
173
+ click: null,
174
+ triggerOnTouchEnd: true,
175
+ triggerOnTouchLeave:false,
176
+ allowPageScroll: "auto",
177
+ fallbackToMouseEvents: true,
178
+ excludedElements:"button, input, select, textarea, a, .noSwipe"
179
+ };
180
+
181
+
182
+
183
+ /**
184
+ * Applies TouchSwipe behaviour to one or more jQuery objects.
185
+ * The TouchSwipe plugin can be instantiated via this method, or methods within
186
+ * TouchSwipe can be executed via this method as per jQuery plugin architecture.
187
+ * @see TouchSwipe
188
+ * @class
189
+ * @param {Mixed} method If the current DOMNode is a TouchSwipe object, and <code>method</code> is a TouchSwipe method, then
190
+ * the <code>method</code> is executed, and any following arguments are passed to the TouchSwipe method.
191
+ * If <code>method</code> is an object, then the TouchSwipe class is instantiated on the current DOMNode, passing the
192
+ * configuration properties defined in the object. See TouchSwipe
193
+ *
194
+ */
195
+ $.fn.swipe = function (method) {
196
+ var $this = $(this),
197
+ plugin = $this.data(PLUGIN_NS);
198
+
199
+ //Check if we are already instantiated and trying to execute a method
200
+ if (plugin && typeof method === 'string') {
201
+ if (plugin[method]) {
202
+ return plugin[method].apply(this, Array.prototype.slice.call(arguments, 1));
203
+ } else {
204
+ $.error('Method ' + method + ' does not exist on jQuery.swipe');
205
+ }
206
+ }
207
+ //Else not instantiated and trying to pass init object (or nothing)
208
+ else if (!plugin && (typeof method === 'object' || !method)) {
209
+ return init.apply(this, arguments);
210
+ }
211
+
212
+ return $this;
213
+ };
214
+
215
+ //Expose our defaults so a user could override the plugin defaults
216
+ $.fn.swipe.defaults = defaults;
217
+
218
+ /**
219
+ * The phases that a touch event goes through. The <code>phase</code> is passed to the event handlers.
220
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
221
+ * @namespace
222
+ * @readonly
223
+ * @property {string} PHASE_START Constant indicating the start phase of the touch event. Value is <code>"start"</code>.
224
+ * @property {string} PHASE_MOVE Constant indicating the move phase of the touch event. Value is <code>"move"</code>.
225
+ * @property {string} PHASE_END Constant indicating the end phase of the touch event. Value is <code>"end"</code>.
226
+ * @property {string} PHASE_CANCEL Constant indicating the cancel phase of the touch event. Value is <code>"cancel"</code>.
227
+ */
228
+ $.fn.swipe.phases = {
229
+ PHASE_START: PHASE_START,
230
+ PHASE_MOVE: PHASE_MOVE,
231
+ PHASE_END: PHASE_END,
232
+ PHASE_CANCEL: PHASE_CANCEL
233
+ };
234
+
235
+ /**
236
+ * The direction constants that are passed to the event handlers.
237
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
238
+ * @namespace
239
+ * @readonly
240
+ * @property {string} LEFT Constant indicating the left direction. Value is <code>"left"</code>.
241
+ * @property {string} RIGHT Constant indicating the right direction. Value is <code>"right"</code>.
242
+ * @property {string} UP Constant indicating the up direction. Value is <code>"up"</code>.
243
+ * @property {string} DOWN Constant indicating the down direction. Value is <code>"cancel"</code>.
244
+ * @property {string} IN Constant indicating the in direction. Value is <code>"in"</code>.
245
+ * @property {string} OUT Constant indicating the out direction. Value is <code>"out"</code>.
246
+ */
247
+ $.fn.swipe.directions = {
248
+ LEFT: LEFT,
249
+ RIGHT: RIGHT,
250
+ UP: UP,
251
+ DOWN: DOWN,
252
+ IN : IN,
253
+ OUT: OUT
254
+ };
255
+
256
+ /**
257
+ * The page scroll constants that can be used to set the value of <code>allowPageScroll</code> option
258
+ * These properties are read only
259
+ * @namespace
260
+ * @readonly
261
+ * @see $.fn.swipe.defaults#allowPageScroll
262
+ * @property {string} NONE Constant indicating no page scrolling is allowed. Value is <code>"none"</code>.
263
+ * @property {string} HORIZONTAL Constant indicating horizontal page scrolling is allowed. Value is <code>"horizontal"</code>.
264
+ * @property {string} VERTICAL Constant indicating vertical page scrolling is allowed. Value is <code>"vertical"</code>.
265
+ * @property {string} AUTO Constant indicating either horizontal or vertical will be allowed, depending on the swipe handlers registered. Value is <code>"auto"</code>.
266
+ */
267
+ $.fn.swipe.pageScroll = {
268
+ NONE: NONE,
269
+ HORIZONTAL: HORIZONTAL,
270
+ VERTICAL: VERTICAL,
271
+ AUTO: AUTO
272
+ };
273
+
274
+ /**
275
+ * Constants representing the number of fingers used in a swipe. These are used to set both the value of <code>fingers</code> in the
276
+ * options object, as well as the value of the <code>fingers</code> event property.
277
+ * These properties are read only, attempting to change them will not alter the values passed to the event handlers.
278
+ * @namespace
279
+ * @readonly
280
+ * @see $.fn.swipe.defaults#fingers
281
+ * @property {string} ONE Constant indicating 1 finger is to be detected / was detected. Value is <code>1</code>.
282
+ * @property {string} TWO Constant indicating 2 fingers are to be detected / were detected. Value is <code>1</code>.
283
+ * @property {string} THREE Constant indicating 3 finger are to be detected / were detected. Value is <code>1</code>.
284
+ * @property {string} ALL Constant indicating any combination of finger are to be detected. Value is <code>"all"</code>.
285
+ */
286
+ $.fn.swipe.fingers = {
287
+ ONE: 1,
288
+ TWO: 2,
289
+ THREE: 3,
290
+ ALL: ALL_FINGERS
291
+ };
292
+
293
+ /**
294
+ * Initialise the plugin for each DOM element matched
295
+ * This creates a new instance of the main TouchSwipe class for each DOM element, and then
296
+ * saves a reference to that instance in the elements data property.
297
+ * @internal
298
+ */
299
+ function init(options) {
300
+ //Prep and extend the options
301
+ if (options && (options.allowPageScroll === undefined && (options.swipe !== undefined || options.swipeStatus !== undefined))) {
302
+ options.allowPageScroll = NONE;
303
+ }
304
+
305
+ if (!options) {
306
+ options = {};
307
+ }
308
+
309
+ //pass empty object so we dont modify the defaults
310
+ options = $.extend({}, $.fn.swipe.defaults, options);
311
+
312
+ //For each element instantiate the plugin
313
+ return this.each(function () {
314
+ var $this = $(this);
315
+
316
+ //Check we havent already initialised the plugin
317
+ var plugin = $this.data(PLUGIN_NS);
318
+
319
+ if (!plugin) {
320
+ plugin = new touchSwipe(this, options);
321
+ $this.data(PLUGIN_NS, plugin);
322
+ }
323
+ });
324
+ }
325
+
326
+ /**
327
+ * Main TouchSwipe Plugin Class.
328
+ * Do not use this to construct your TouchSwipe object, use the jQuery plugin method $.fn.swipe(); {@link $.fn.swipe}
329
+ * @private
330
+ * @name TouchSwipe
331
+ * @param {DOMNode} element The HTML DOM object to apply to plugin to
332
+ * @param {Object} options The options to configure the plugin with. @link {$.fn.swipe.defaults}
333
+ * @see $.fh.swipe.defaults
334
+ * @see $.fh.swipe
335
+ * @class
336
+ */
337
+ function touchSwipe(element, options) {
338
+ var useTouchEvents = (SUPPORTS_TOUCH || !options.fallbackToMouseEvents),
339
+ START_EV = useTouchEvents ? 'touchstart' : 'mousedown',
340
+ MOVE_EV = useTouchEvents ? 'touchmove' : 'mousemove',
341
+ END_EV = useTouchEvents ? 'touchend' : 'mouseup',
342
+ LEAVE_EV = useTouchEvents ? null : 'mouseleave', //we manually detect leave on touch devices, so null event here
343
+ CANCEL_EV = 'touchcancel';
344
+
345
+
346
+
347
+ //touch properties
348
+ var distance = 0;
349
+ var direction = null;
350
+ var duration = 0;
351
+ var startTouchesDistance=0;
352
+ var endTouchesDistance=0;
353
+ var pinchZoom = 1;
354
+ var pinchDirection=0;
355
+
356
+
357
+ //jQuery wrapped element for this instance
358
+ var $element = $(element);
359
+
360
+ //Current phase of th touch cycle
361
+ var phase = "start";
362
+
363
+ // the current number of fingers being used.
364
+ var fingerCount = 0;
365
+
366
+ //track mouse points / delta
367
+ var fingerData=null;
368
+
369
+ //track times
370
+ var startTime = 0;
371
+ var endTime = 0;
372
+ var previousTouchEndTime=0;
373
+ var previousTouchFingerCount=0;
374
+
375
+ // Add gestures to all swipable areas if supported
376
+ try {
377
+ $element.bind(START_EV, touchStart);
378
+ $element.bind(CANCEL_EV, touchCancel);
379
+ }
380
+ catch (e) {
381
+ $.error('events not supported ' + START_EV + ',' + CANCEL_EV + ' on jQuery.swipe');
382
+ }
383
+
384
+ //
385
+ //Public methods
386
+ //
387
+
388
+ /**
389
+ * re-enables the swipe plugin with the previous configuration
390
+ * @function
391
+ * @name $.fn.swipe#enable
392
+ * @return {DOMNode} The Dom element that was registered with TouchSwipe
393
+ * @example $("#element").swipe("enable");
394
+ */
395
+ this.enable = function () {
396
+ $element.bind(START_EV, touchStart);
397
+ $element.bind(CANCEL_EV, touchCancel);
398
+ return $element;
399
+ };
400
+
401
+ /**
402
+ * disables the swipe plugin
403
+ * @function
404
+ * @name $.fn.swipe#disable
405
+ * @return {DOMNode} The Dom element that is now registered with TouchSwipe
406
+ * @example $("#element").swipe("disable");
407
+ */
408
+ this.disable = function () {
409
+ removeListeners();
410
+ return $element;
411
+ };
412
+
413
+ /**
414
+ * Destroy the swipe plugin completely. To use any swipe methods, you must re initialise the plugin.
415
+ * @function
416
+ * @name $.fn.swipe#destroy
417
+ * @return {DOMNode} The Dom element that was registered with TouchSwipe
418
+ * @example $("#element").swipe("destroy");
419
+ */
420
+ this.destroy = function () {
421
+ removeListeners();
422
+ $element.data(PLUGIN_NS, null);
423
+ return $element;
424
+ };
425
+
426
+
427
+ //
428
+ // Private methods
429
+ //
430
+
431
+ //
432
+ // EVENTS
433
+ //
434
+ /**
435
+ * Event handler for a touch start event.
436
+ * Stops the default click event from triggering and stores where we touched
437
+ * @inner
438
+ * @param {object} jqEvent The normalised jQuery event object.
439
+ */
440
+ function touchStart(jqEvent) {
441
+ //If we already in a touch event (a finger already in use) then ignore subsequent ones..
442
+ if( getTouchInProgress() )
443
+ return;
444
+
445
+ //Check if this element matches any in the excluded elements selectors, or its parent is excluded, if so, DONT swipe
446
+ if( $(jqEvent.target).closest( options.excludedElements, $element ).length>0 )
447
+ return;
448
+
449
+ //As we use Jquery bind for events, we need to target the original event object
450
+ var event = jqEvent.originalEvent;
451
+
452
+ var ret,
453
+ evt = SUPPORTS_TOUCH ? event.touches[0] : event;
454
+
455
+ phase = PHASE_START;
456
+
457
+ //If we support touches, get the finger count
458
+ if (SUPPORTS_TOUCH) {
459
+ // get the total number of fingers touching the screen
460
+ fingerCount = event.touches.length;
461
+ }
462
+ //Else this is the desktop, so stop the browser from dragging the image
463
+ else {
464
+ jqEvent.preventDefault(); //call this on jq event so we are cross browser
465
+ }
466
+
467
+ //clear vars..
468
+ distance = 0;
469
+ direction = null;
470
+ pinchDirection=null;
471
+ duration = 0;
472
+ startTouchesDistance=0;
473
+ endTouchesDistance=0;
474
+ pinchZoom = 1;
475
+ pinchDistance = 0;
476
+ fingerData=createAllFingerData();
477
+ cancelMultiFingerRelease();
478
+
479
+
480
+ // check the number of fingers is what we are looking for, or we are capturing pinches
481
+ if (!SUPPORTS_TOUCH || (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || hasPinches()) {
482
+ // get the coordinates of the touch
483
+ createFingerData( 0, evt );
484
+ startTime = getTimeStamp();
485
+
486
+ if(fingerCount==2) {
487
+ //Keep track of the initial pinch distance, so we can calculate the diff later
488
+ //Store second finger data as start
489
+ createFingerData( 1, event.touches[1] );
490
+ startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
491
+ }
492
+
493
+ if (options.swipeStatus || options.pinchStatus) {
494
+ ret = triggerHandler(event, phase);
495
+ }
496
+ }
497
+ else {
498
+ //A touch with more or less than the fingers we are looking for, so cancel
499
+ ret = false;
500
+ }
501
+
502
+ //If we have a return value from the users handler, then return and cancel
503
+ if (ret === false) {
504
+ phase = PHASE_CANCEL;
505
+ triggerHandler(event, phase);
506
+ return ret;
507
+ }
508
+ else {
509
+ setTouchInProgress(true);
510
+ }
511
+ };
512
+
513
+
514
+
515
+ /**
516
+ * Event handler for a touch move event.
517
+ * If we change fingers during move, then cancel the event
518
+ * @inner
519
+ * @param {object} jqEvent The normalised jQuery event object.
520
+ */
521
+ function touchMove(jqEvent) {
522
+
523
+ //As we use Jquery bind for events, we need to target the original event object
524
+ var event = jqEvent.originalEvent;
525
+
526
+ //If we are ending, cancelling, or within the threshold of 2 fingers being released, dont track anything..
527
+ if (phase === PHASE_END || phase === PHASE_CANCEL || inMultiFingerRelease())
528
+ return;
529
+
530
+ var ret,
531
+ evt = SUPPORTS_TOUCH ? event.touches[0] : event;
532
+
533
+
534
+ //Update the finger data
535
+ var currentFinger = updateFingerData(evt);
536
+ endTime = getTimeStamp();
537
+
538
+ if (SUPPORTS_TOUCH) {
539
+ fingerCount = event.touches.length;
540
+ }
541
+
542
+ phase = PHASE_MOVE;
543
+
544
+ //If we have 2 fingers get Touches distance as well
545
+ if(fingerCount==2) {
546
+
547
+ //Keep track of the initial pinch distance, so we can calculate the diff later
548
+ //We do this here as well as the start event, incase they start with 1 finger, and the press 2 fingers
549
+ if(startTouchesDistance==0) {
550
+ //Create second finger if this is the first time...
551
+ createFingerData( 1, event.touches[1] );
552
+
553
+ startTouchesDistance = endTouchesDistance = calculateTouchesDistance(fingerData[0].start, fingerData[1].start);
554
+ } else {
555
+ //Else just update the second finger
556
+ updateFingerData(event.touches[1]);
557
+
558
+ endTouchesDistance = calculateTouchesDistance(fingerData[0].end, fingerData[1].end);
559
+ pinchDirection = calculatePinchDirection(fingerData[0].end, fingerData[1].end);
560
+ }
561
+
562
+
563
+ pinchZoom = calculatePinchZoom(startTouchesDistance, endTouchesDistance);
564
+ pinchDistance = Math.abs(startTouchesDistance - endTouchesDistance);
565
+ }
566
+
567
+
568
+ if ( (fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH || hasPinches() ) {
569
+
570
+ direction = calculateDirection(currentFinger.start, currentFinger.end);
571
+
572
+ //Check if we need to prevent default evnet (page scroll / pinch zoom) or not
573
+ validateDefaultEvent(jqEvent, direction);
574
+
575
+ //Distance and duration are all off the main finger
576
+ distance = calculateDistance(currentFinger.start, currentFinger.end);
577
+ duration = calculateDuration();
578
+
579
+ if (options.swipeStatus || options.pinchStatus) {
580
+ ret = triggerHandler(event, phase);
581
+ }
582
+
583
+
584
+ //If we trigger end events when threshold are met, or trigger events when touch leves element
585
+ if(!options.triggerOnTouchEnd || options.triggerOnTouchLeave) {
586
+
587
+ var inBounds = true;
588
+
589
+ //If checking if we leave the element, run the bounds check (we can use touchleave as its not supported on webkit)
590
+ if(options.triggerOnTouchLeave) {
591
+ var bounds = getbounds( this );
592
+ inBounds = isInBounds( currentFinger.end, bounds );
593
+ }
594
+
595
+ //Trigger end handles as we swipe if thresholds met or if we have left the element if the user has asked to check these..
596
+ if(!options.triggerOnTouchEnd && inBounds) {
597
+ phase = getNextPhase( PHASE_MOVE );
598
+ }
599
+ //We end if out of bounds here, so set current phase to END, and check if its modified
600
+ else if(options.triggerOnTouchLeave && !inBounds ) {
601
+ phase = getNextPhase( PHASE_END );
602
+ }
603
+
604
+ if(phase==PHASE_CANCEL || phase==PHASE_END) {
605
+ triggerHandler(event, phase);
606
+ }
607
+ }
608
+ }
609
+ else {
610
+ phase = PHASE_CANCEL;
611
+ triggerHandler(event, phase);
612
+ }
613
+
614
+ if (ret === false) {
615
+ phase = PHASE_CANCEL;
616
+ triggerHandler(event, phase);
617
+ }
618
+ }
619
+
620
+
621
+
622
+ /**
623
+ * Event handler for a touch end event.
624
+ * Calculate the direction and trigger events
625
+ * @inner
626
+ * @param {object} jqEvent The normalised jQuery event object.
627
+ */
628
+ function touchEnd(jqEvent) {
629
+ //As we use Jquery bind for events, we need to target the original event object
630
+ var event = jqEvent.originalEvent;
631
+
632
+
633
+ //If we are still in a touch with another finger return
634
+ //This allows us to wait a fraction and see if the other finger comes up, if it does within the threshold, then we treat it as a multi release, not a single release.
635
+ if (SUPPORTS_TOUCH) {
636
+ if(event.touches.length>0) {
637
+ startMultiFingerRelease();
638
+ return true;
639
+ }
640
+ }
641
+
642
+ //If a previous finger has been released, check how long ago, if within the threshold, then assume it was a multifinger release.
643
+ //This is used to allow 2 fingers to release fractionally after each other, whilst maintainig the event as containg 2 fingers, not 1
644
+ if(inMultiFingerRelease()) {
645
+ fingerCount=previousTouchFingerCount;
646
+ }
647
+
648
+ //call this on jq event so we are cross browser
649
+ jqEvent.preventDefault();
650
+
651
+ //Set end of swipe
652
+ endTime = getTimeStamp();
653
+
654
+
655
+ //If we trigger handlers at end of swipe OR, we trigger during, but they didnt trigger and we are still in the move phase
656
+ if (options.triggerOnTouchEnd || (options.triggerOnTouchEnd == false && phase === PHASE_MOVE)) {
657
+ phase = PHASE_END;
658
+
659
+ //The number of fingers we want were matched, or on desktop we ignore
660
+ var hasCorrectFingerCount = ((fingerCount === options.fingers || options.fingers === ALL_FINGERS) || !SUPPORTS_TOUCH);
661
+
662
+ //We have an end value for the finger
663
+ var hasEndPoint = fingerData[0].end.x !== 0;
664
+
665
+ //Check if the above conditions are met to make this swipe count...
666
+ var isSwipe = hasCorrectFingerCount && hasEndPoint && (validatePinch() || validateSwipe());
667
+
668
+ //If we are in a swipe, validate the time and distance...
669
+ if (isSwipe) {
670
+ triggerHandler(event, phase);
671
+ } else {
672
+ phase = PHASE_CANCEL;
673
+ triggerHandler(event, phase);
674
+ }
675
+ }
676
+ else if (phase === PHASE_MOVE) {
677
+ phase = PHASE_CANCEL;
678
+ triggerHandler(event, phase);
679
+ }
680
+
681
+ setTouchInProgress(false);
682
+ }
683
+
684
+
685
+
686
+ /**
687
+ * Event handler for a touch cancel event.
688
+ * Clears current vars
689
+ * @inner
690
+ */
691
+ function touchCancel() {
692
+ // reset the variables back to default values
693
+ fingerCount = 0;
694
+ endTime = 0;
695
+ startTime = 0;
696
+ startTouchesDistance=0;
697
+ endTouchesDistance=0;
698
+ pinchZoom=1;
699
+
700
+ //If we were in progress of tracking a possible multi touch end, then re set it.
701
+ cancelMultiFingerRelease();
702
+
703
+ setTouchInProgress(false);
704
+ }
705
+
706
+
707
+ /**
708
+ * Event handler for a touch leave event.
709
+ * This is only triggered on desktops, in touch we work this out manually
710
+ * as the touchleave event is not supported in webkit
711
+ * @inner
712
+ */
713
+ function touchLeave(jqEvent) {
714
+ var event = jqEvent.originalEvent;
715
+
716
+ //If we have the trigger on leve property set....
717
+ if(options.triggerOnTouchLeave) {
718
+ phase = getNextPhase( PHASE_END );
719
+ triggerHandler(event, phase);
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Removes all listeners that were associated with the plugin
725
+ * @inner
726
+ */
727
+ function removeListeners() {
728
+ $element.unbind(START_EV, touchStart);
729
+ $element.unbind(CANCEL_EV, touchCancel);
730
+ $element.unbind(MOVE_EV, touchMove);
731
+ $element.unbind(END_EV, touchEnd);
732
+
733
+ //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
734
+ if(LEAVE_EV) {
735
+ $element.unbind(LEAVE_EV, touchLeave);
736
+ }
737
+
738
+ setTouchInProgress(false);
739
+ }
740
+
741
+
742
+ /**
743
+ * Checks if the time and distance thresholds have been met, and if so then the appropriate handlers are fired.
744
+ */
745
+ function getNextPhase(currentPhase) {
746
+
747
+ var nextPhase = currentPhase;
748
+
749
+ // Ensure we have valid swipe (under time and over distance and check if we are out of bound...)
750
+ var validTime = validateSwipeTime();
751
+ var validDistance = validateSwipeDistance();
752
+
753
+
754
+ //If we have exceeded our time, then cancel
755
+ if(!validTime) {
756
+ nextPhase = PHASE_CANCEL;
757
+ }
758
+ //Else if we are moving, and have reached distance then end
759
+ else if (validDistance && currentPhase == PHASE_MOVE && (!options.triggerOnTouchEnd || options.triggerOnTouchLeave) ) {
760
+ nextPhase = PHASE_END;
761
+ }
762
+ //Else if we have ended by leaving and didnt reach distance, then cancel
763
+ else if (!validDistance && currentPhase==PHASE_END && options.triggerOnTouchLeave) {
764
+ nextPhase = PHASE_CANCEL;
765
+ }
766
+
767
+
768
+ return nextPhase;
769
+ }
770
+
771
+
772
+ /**
773
+ * Trigger the relevant event handler
774
+ * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
775
+ * @param {object} event the original event object
776
+ * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
777
+ * @inner
778
+ */
779
+ function triggerHandler(event, phase) {
780
+
781
+ var ret = undefined;
782
+
783
+ // SWIPE GESTURES
784
+ if(hasSwipes()) {
785
+ //Trigger the swipe events...
786
+ ret = triggerHandlerForGesture(event, phase, SWIPE);
787
+ }
788
+
789
+ // PINCH GESTURES (if the above didnt cancel)
790
+ if(hasPinches() && ret!==false) {
791
+ //Trigger the pinch events...
792
+ ret = triggerHandlerForGesture(event, phase, PINCH);
793
+ }
794
+
795
+ // CLICKS / TAPS (if the above didnt cancel)
796
+ if(hasClick() && ret!==false) {
797
+ //Trigger the pinch events...
798
+ ret = triggerHandlerForGesture(event, phase, CLICK);
799
+ }
800
+
801
+ // If we are cancelling the gesture, then manually trigger the reset handler
802
+ if (phase === PHASE_CANCEL) {
803
+ touchCancel(event);
804
+ }
805
+
806
+ // If we are ending the gesture, then manually trigger the reset handler IF all fingers are off
807
+ if(phase === PHASE_END) {
808
+ //If we support touch, then check that all fingers are off before we cancel
809
+ if (SUPPORTS_TOUCH) {
810
+ if(event.touches.length==0) {
811
+ touchCancel(event);
812
+ }
813
+ }
814
+ else {
815
+ touchCancel(event);
816
+ }
817
+ }
818
+
819
+ return ret;
820
+ }
821
+
822
+
823
+
824
+ /**
825
+ * Trigger the relevant event handler
826
+ * The handlers are passed the original event, the element that was swiped, and in the case of the catch all handler, the direction that was swiped, "left", "right", "up", or "down"
827
+ * @param {object} event the original event object
828
+ * @param {string} phase the phase of the swipe (start, end cancel etc) {@link $.fn.swipe.phases}
829
+ * @param {string} gesture the gesture to triger a handler for : PINCH or SWIPE {@link $.fn.swipe.gestures}
830
+ * @return Boolean False, to indicate that the event should stop propagation, or void.
831
+ * @inner
832
+ */
833
+ function triggerHandlerForGesture(event, phase, gesture) {
834
+
835
+ var ret=undefined;
836
+
837
+ //SWIPES....
838
+ if(gesture==SWIPE) {
839
+ //Trigger status every time..
840
+ if (options.swipeStatus) {
841
+ ret = options.swipeStatus.call($element, event, phase, direction || null, distance || 0, duration || 0, fingerCount);
842
+ //If the status cancels, then dont run the subsequent event handlers..
843
+ if(ret===false) return false;
844
+ }
845
+
846
+
847
+ if (phase == PHASE_END && validateSwipe()) {
848
+ //trigger catch all event handler
849
+ if (options.swipe) {
850
+ ret = options.swipe.call($element, event, direction, distance, duration, fingerCount);
851
+ //If the status cancels, then dont run the subsequent event handlers..
852
+ if(ret===false) return false;
853
+ }
854
+
855
+ //trigger direction specific event handlers
856
+ switch (direction) {
857
+ case LEFT:
858
+ if (options.swipeLeft) {
859
+ ret = options.swipeLeft.call($element, event, direction, distance, duration, fingerCount);
860
+ }
861
+ break;
862
+
863
+ case RIGHT:
864
+ if (options.swipeRight) {
865
+ ret = options.swipeRight.call($element, event, direction, distance, duration, fingerCount);
866
+ }
867
+ break;
868
+
869
+ case UP:
870
+ if (options.swipeUp) {
871
+ ret = options.swipeUp.call($element, event, direction, distance, duration, fingerCount);
872
+ }
873
+ break;
874
+
875
+ case DOWN:
876
+ if (options.swipeDown) {
877
+ ret = options.swipeDown.call($element, event, direction, distance, duration, fingerCount);
878
+ }
879
+ break;
880
+ }
881
+ }
882
+ }
883
+
884
+
885
+ //PINCHES....
886
+ if(gesture==PINCH) {
887
+ //Trigger status every time
888
+ if (options.pinchStatus) {
889
+ ret = options.pinchStatus.call($element, event, phase, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom);
890
+ //If the status cancels, then dont run the subsequent event handlers..
891
+ if(ret===false) return false;
892
+ }
893
+
894
+ if(phase==PHASE_END && validatePinch()) {
895
+
896
+ switch (pinchDirection) {
897
+ case IN:
898
+ if (options.pinchIn) {
899
+ ret = options.pinchIn.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom);
900
+ }
901
+ break;
902
+
903
+ case OUT:
904
+ if (options.pinchOut) {
905
+ ret = options.pinchOut.call($element, event, pinchDirection || null, pinchDistance || 0, duration || 0, fingerCount, pinchZoom);
906
+ }
907
+ break;
908
+ }
909
+ }
910
+ }
911
+
912
+
913
+ //CLICKS...
914
+ if(gesture==CLICK) {
915
+ if(phase === PHASE_CANCEL) {
916
+ if (options.click && (fingerCount === 1 || !SUPPORTS_TOUCH) && (isNaN(distance) || distance === 0)) {
917
+ ret = options.click.call($element, event, event.target);
918
+ }
919
+ }
920
+ }
921
+
922
+ return ret;
923
+ }
924
+
925
+
926
+
927
+
928
+ //
929
+ // GESTURE VALIDATION
930
+ //
931
+
932
+ /**
933
+ * Checks the user has swipe far enough
934
+ * @return Boolean if <code>threshold</code> has been set, return true if the threshold was met, else false.
935
+ * If no threshold was set, then we return true.
936
+ * @inner
937
+ */
938
+ function validateSwipeDistance() {
939
+ if (options.threshold !== null) {
940
+ return distance >= options.threshold;
941
+ }
942
+
943
+ return true;
944
+ }
945
+
946
+ /**
947
+ * Checks the user has pinched far enough
948
+ * @return Boolean if <code>pinchThreshold</code> has been set, return true if the threshold was met, else false.
949
+ * If no threshold was set, then we return true.
950
+ * @inner
951
+ */
952
+ function validatePinchDistance() {
953
+ if (options.pinchThreshold !== null) {
954
+ return pinchDistance >= options.pinchThreshold;
955
+ }
956
+ return true;
957
+ }
958
+
959
+ /**
960
+ * Checks that the time taken to swipe meets the minimum / maximum requirements
961
+ * @return Boolean
962
+ * @inner
963
+ */
964
+ function validateSwipeTime() {
965
+ var result;
966
+ //If no time set, then return true
967
+
968
+ if (options.maxTimeThreshold) {
969
+ if (duration >= options.maxTimeThreshold) {
970
+ result = false;
971
+ } else {
972
+ result = true;
973
+ }
974
+ }
975
+ else {
976
+ result = true;
977
+ }
978
+
979
+ return result;
980
+ }
981
+
982
+
983
+ /**
984
+ * Checks direction of the swipe and the value allowPageScroll to see if we should allow or prevent the default behaviour from occurring.
985
+ * This will essentially allow page scrolling or not when the user is swiping on a touchSwipe object.
986
+ * @param {object} jqEvent The normalised jQuery representation of the event object.
987
+ * @param {string} direction The direction of the event. See {@link $.fn.swipe.directions}
988
+ * @see $.fn.swipe.directions
989
+ * @inner
990
+ */
991
+ function validateDefaultEvent(jqEvent, direction) {
992
+ if (options.allowPageScroll === NONE || hasPinches()) {
993
+ jqEvent.preventDefault();
994
+ } else {
995
+ var auto = options.allowPageScroll === AUTO;
996
+
997
+ switch (direction) {
998
+ case LEFT:
999
+ if ((options.swipeLeft && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
1000
+ jqEvent.preventDefault();
1001
+ }
1002
+ break;
1003
+
1004
+ case RIGHT:
1005
+ if ((options.swipeRight && auto) || (!auto && options.allowPageScroll != HORIZONTAL)) {
1006
+ jqEvent.preventDefault();
1007
+ }
1008
+ break;
1009
+
1010
+ case UP:
1011
+ if ((options.swipeUp && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
1012
+ jqEvent.preventDefault();
1013
+ }
1014
+ break;
1015
+
1016
+ case DOWN:
1017
+ if ((options.swipeDown && auto) || (!auto && options.allowPageScroll != VERTICAL)) {
1018
+ jqEvent.preventDefault();
1019
+ }
1020
+ break;
1021
+ }
1022
+ }
1023
+
1024
+ }
1025
+
1026
+
1027
+ // PINCHES
1028
+ /**
1029
+ * Returns true of the current pinch meets the thresholds
1030
+ * @return Boolean
1031
+ * @inner
1032
+ */
1033
+ function validatePinch() {
1034
+ return validatePinchDistance();;
1035
+ }
1036
+
1037
+ /**
1038
+ * Returns true if any Pinch events have been registered
1039
+ * @return Boolean
1040
+ * @inner
1041
+ */
1042
+ function hasPinches() {
1043
+ //Enure we dont return 0 or null for false values
1044
+ return !!(options.pinchStatus || options.pinchIn || options.pinchOut);
1045
+ }
1046
+
1047
+ /**
1048
+ * Returns true if we are detecting pinches, and have one
1049
+ * @return Boolean
1050
+ * @inner
1051
+ */
1052
+ function didPinch() {
1053
+ //Enure we dont return 0 or null for false values
1054
+ return !!(validatePinch() && hasPinches());
1055
+ }
1056
+
1057
+
1058
+
1059
+
1060
+ // SWIPES
1061
+ /**
1062
+ * Returns true if the current swipe meets the thresholds
1063
+ * @return Boolean
1064
+ * @inner
1065
+ */
1066
+ function validateSwipe() {
1067
+ //Check validity of swipe
1068
+ var hasValidTime = validateSwipeTime();
1069
+ var hasValidDistance = validateSwipeDistance();
1070
+
1071
+ // if the user swiped more than the minimum length, perform the appropriate action
1072
+ // hasValidDistance is null when no distance is set
1073
+ var valid = hasValidDistance && hasValidTime;
1074
+
1075
+ return valid;
1076
+ }
1077
+
1078
+ /**
1079
+ * Returns true if any Swipe events have been registered
1080
+ * @return Boolean
1081
+ * @inner
1082
+ */
1083
+ function hasSwipes() {
1084
+ //Enure we dont return 0 or null for false values
1085
+ return !!(options.swipe || options.swipeStatus || options.swipeLeft || options.swipeRight || options.swipeUp || options.swipeDown);
1086
+ }
1087
+
1088
+
1089
+ /**
1090
+ * Returns true if we are detecting swipes and have one
1091
+ * @return Boolean
1092
+ * @inner
1093
+ */
1094
+ function didSwipe() {
1095
+ //Enure we dont return 0 or null for false values
1096
+ return !!(validateSwipe() && hasSwipes());
1097
+ }
1098
+
1099
+
1100
+ // TAP / CLICK
1101
+ /**
1102
+ * Returns true of any clcik / tap evetns have been registered
1103
+ * @return Boolean
1104
+ * @inner
1105
+ */
1106
+ function hasClick() {
1107
+ //Enure we dont return 0 or null for false values
1108
+ return !!(options.click);
1109
+ }
1110
+
1111
+
1112
+ // MULTI FINGER TOUCH
1113
+ /**
1114
+ * Starts tracking the time between 2 finger releases, and keeps track of how many fingers we initially had up
1115
+ * @inner
1116
+ */
1117
+ function startMultiFingerRelease() {
1118
+ previousTouchEndTime = getTimeStamp();
1119
+ previousTouchFingerCount = event.touches.length+1;
1120
+ }
1121
+
1122
+ /**
1123
+ * Cancels the tracking of time between 2 finger releases, and resets counters
1124
+ * @inner
1125
+ */
1126
+ function cancelMultiFingerRelease() {
1127
+ previousTouchEndTime = 0;
1128
+ previousTouchFingerCount = 0;
1129
+ }
1130
+
1131
+ /**
1132
+ * Checks if we are in the threshold between 2 fingers being released
1133
+ * @return Boolean
1134
+ * @inner
1135
+ */
1136
+ function inMultiFingerRelease() {
1137
+
1138
+ var withinThreshold = false;
1139
+
1140
+ if(previousTouchEndTime) {
1141
+ var diff = getTimeStamp() - previousTouchEndTime
1142
+ if( diff<=options.fingerReleaseThreshold ) {
1143
+ withinThreshold = true;
1144
+ }
1145
+ }
1146
+
1147
+ return withinThreshold;
1148
+ }
1149
+
1150
+
1151
+ /**
1152
+ * gets a data flag to indicate that a touch is in progress
1153
+ * @return Boolean
1154
+ * @inner
1155
+ */
1156
+ function getTouchInProgress() {
1157
+ //strict equality to ensure only true and false are returned
1158
+ return !!($element.data(PLUGIN_NS+'_intouch') === true);
1159
+ }
1160
+
1161
+ /**
1162
+ * Sets a data flag to indicate that a touch is in progress
1163
+ * @param {boolean} val The value to set the property to
1164
+ * @inner
1165
+ */
1166
+ function setTouchInProgress(val) {
1167
+
1168
+ //Add or remove event listeners depending on touch status
1169
+ if(val===true) {
1170
+ $element.bind(MOVE_EV, touchMove);
1171
+ $element.bind(END_EV, touchEnd);
1172
+
1173
+ //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
1174
+ if(LEAVE_EV) {
1175
+ $element.bind(LEAVE_EV, touchLeave);
1176
+ }
1177
+ } else {
1178
+ $element.unbind(MOVE_EV, touchMove, false);
1179
+ $element.unbind(END_EV, touchEnd, false);
1180
+
1181
+ //we only have leave events on desktop, we manually calcuate leave on touch as its not supported in webkit
1182
+ if(LEAVE_EV) {
1183
+ $element.unbind(LEAVE_EV, touchLeave, false);
1184
+ }
1185
+ }
1186
+
1187
+
1188
+ //strict equality to ensure only true and false can update the value
1189
+ $element.data(PLUGIN_NS+'_intouch', val === true);
1190
+ }
1191
+
1192
+
1193
+ /**
1194
+ * Creates the finger data for the touch/finger in the event object.
1195
+ * @param {int} index The index in the array to store the finger data (usually the order the fingers were pressed)
1196
+ * @param {object} evt The event object containing finger data
1197
+ * @return finger data object
1198
+ * @inner
1199
+ */
1200
+ function createFingerData( index, evt ) {
1201
+ var id = evt.identifier!==undefined ? evt.identifier : 0;
1202
+
1203
+ fingerData[index].identifier = id;
1204
+ fingerData[index].start.x = fingerData[index].end.x = evt.pageX;
1205
+ fingerData[index].start.y = fingerData[index].end.y = evt.pageY;
1206
+
1207
+ return fingerData[index];
1208
+ }
1209
+
1210
+ /**
1211
+ * Updates the finger data for a particular event object
1212
+ * @param {object} evt The event object containing the touch/finger data to upadte
1213
+ * @return a finger data object.
1214
+ * @inner
1215
+ */
1216
+ function updateFingerData(evt) {
1217
+
1218
+ var id = evt.identifier!==undefined ? evt.identifier : 0;
1219
+ var f = getFingerData( id );
1220
+
1221
+ f.end.x = evt.pageX;
1222
+ f.end.y = evt.pageY;
1223
+
1224
+ return f;
1225
+ }
1226
+
1227
+ /**
1228
+ * Returns a finger data object by its event ID.
1229
+ * Each touch event has an identifier property, which is used
1230
+ * to track repeat touches
1231
+ * @param {int} id The unique id of the finger in the sequence of touch events.
1232
+ * @return a finger data object.
1233
+ * @inner
1234
+ */
1235
+ function getFingerData( id ) {
1236
+ for(var i=0; i<fingerData.length; i++) {
1237
+ if(fingerData[i].identifier == id) {
1238
+ return fingerData[i];
1239
+ }
1240
+ }
1241
+ }
1242
+
1243
+ /**
1244
+ * Creats all the finger onjects and returns an array of finger data
1245
+ * @return Array of finger objects
1246
+ * @inner
1247
+ */
1248
+ function createAllFingerData() {
1249
+ var fingerData=[];
1250
+ for (var i=0; i<=5; i++) {
1251
+ fingerData.push({
1252
+ start:{ x: 0, y: 0 },
1253
+ end:{ x: 0, y: 0 },
1254
+ identifier:0
1255
+ });
1256
+ }
1257
+
1258
+ return fingerData;
1259
+ }
1260
+
1261
+
1262
+
1263
+
1264
+ //
1265
+ // MATHS / UTILS
1266
+ //
1267
+
1268
+ /**
1269
+ * Calculate the duration of the swipe
1270
+ * @return int
1271
+ * @inner
1272
+ */
1273
+ function calculateDuration() {
1274
+ return endTime - startTime;
1275
+ }
1276
+
1277
+ /**
1278
+ * Calculate the distance between 2 touches (pinch)
1279
+ * @param {point} startPoint A point object containing x and y co-ordinates
1280
+ * @param {point} endPoint A point object containing x and y co-ordinates
1281
+ * @return int;
1282
+ * @inner
1283
+ */
1284
+ function calculateTouchesDistance(startPoint, endPoint) {
1285
+ var diffX = Math.abs(startPoint.x - endPoint.x);
1286
+ var diffY = Math.abs(startPoint.y - endPoint.y);
1287
+
1288
+ return Math.round(Math.sqrt(diffX*diffX+diffY*diffY));
1289
+ }
1290
+
1291
+ /**
1292
+ * Calculate the zoom factor between the start and end distances
1293
+ * @param {int} startDistance Distance (between 2 fingers) the user started pinching at
1294
+ * @param {int} endDistance Distance (between 2 fingers) the user ended pinching at
1295
+ * @return float The zoom value from 0 to 1.
1296
+ * @inner
1297
+ */
1298
+ function calculatePinchZoom(startDistance, endDistance) {
1299
+ var percent = (endDistance/startDistance) * 1;
1300
+ return percent.toFixed(2);
1301
+ }
1302
+
1303
+
1304
+ /**
1305
+ * Returns the pinch direction, either IN or OUT for the given points
1306
+ * @return string Either {@link $.fn.swipe.directions.IN} or {@link $.fn.swipe.directions.OUT}
1307
+ * @see $.fn.swipe.directions
1308
+ * @inner
1309
+ */
1310
+ function calculatePinchDirection() {
1311
+ if(pinchZoom<1) {
1312
+ return OUT;
1313
+ }
1314
+ else {
1315
+ return IN;
1316
+ }
1317
+ }
1318
+
1319
+
1320
+ /**
1321
+ * Calculate the length / distance of the swipe
1322
+ * @param {point} startPoint A point object containing x and y co-ordinates
1323
+ * @param {point} endPoint A point object containing x and y co-ordinates
1324
+ * @return int
1325
+ * @inner
1326
+ */
1327
+ function calculateDistance(startPoint, endPoint) {
1328
+ return Math.round(Math.sqrt(Math.pow(endPoint.x - startPoint.x, 2) + Math.pow(endPoint.y - startPoint.y, 2)));
1329
+ }
1330
+
1331
+ /**
1332
+ * Calculate the angle of the swipe
1333
+ * @param {point} startPoint A point object containing x and y co-ordinates
1334
+ * @param {point} endPoint A point object containing x and y co-ordinates
1335
+ * @return int
1336
+ * @inner
1337
+ */
1338
+ function calculateAngle(startPoint, endPoint) {
1339
+ var x = startPoint.x - endPoint.x;
1340
+ var y = endPoint.y - startPoint.y;
1341
+ var r = Math.atan2(y, x); //radians
1342
+ var angle = Math.round(r * 180 / Math.PI); //degrees
1343
+
1344
+ //ensure value is positive
1345
+ if (angle < 0) {
1346
+ angle = 360 - Math.abs(angle);
1347
+ }
1348
+
1349
+ return angle;
1350
+ }
1351
+
1352
+ /**
1353
+ * Calculate the direction of the swipe
1354
+ * This will also call calculateAngle to get the latest angle of swipe
1355
+ * @param {point} startPoint A point object containing x and y co-ordinates
1356
+ * @param {point} endPoint A point object containing x and y co-ordinates
1357
+ * @return string Either {@link $.fn.swipe.directions.LEFT} / {@link $.fn.swipe.directions.RIGHT} / {@link $.fn.swipe.directions.DOWN} / {@link $.fn.swipe.directions.UP}
1358
+ * @see $.fn.swipe.directions
1359
+ * @inner
1360
+ */
1361
+ function calculateDirection(startPoint, endPoint ) {
1362
+ var angle = calculateAngle(startPoint, endPoint);
1363
+
1364
+ if ((angle <= 45) && (angle >= 0)) {
1365
+ return LEFT;
1366
+ } else if ((angle <= 360) && (angle >= 315)) {
1367
+ return LEFT;
1368
+ } else if ((angle >= 135) && (angle <= 225)) {
1369
+ return RIGHT;
1370
+ } else if ((angle > 45) && (angle < 135)) {
1371
+ return DOWN;
1372
+ } else {
1373
+ return UP;
1374
+ }
1375
+ }
1376
+
1377
+
1378
+ /**
1379
+ * Returns a MS time stamp of the current time
1380
+ * @return int
1381
+ * @inner
1382
+ */
1383
+ function getTimeStamp() {
1384
+ var now = new Date();
1385
+ return now.getTime();
1386
+ }
1387
+
1388
+
1389
+
1390
+ /**
1391
+ * Returns a bounds object with left, right, top and bottom properties for the element specified.
1392
+ * @param {DomNode} The DOM node to get the bounds for.
1393
+ */
1394
+ function getbounds( el ) {
1395
+ el = $(el);
1396
+ var offset = el.offset();
1397
+
1398
+ var bounds = {
1399
+ left:offset.left,
1400
+ right:offset.left+el.outerWidth(),
1401
+ top:offset.top,
1402
+ bottom:offset.top+el.outerHeight()
1403
+ }
1404
+
1405
+ return bounds;
1406
+ }
1407
+
1408
+
1409
+ /**
1410
+ * Checks if the point object is in the bounds object.
1411
+ * @param {object} point A point object.
1412
+ * @param {int} point.x The x value of the point.
1413
+ * @param {int} point.y The x value of the point.
1414
+ * @param {object} bounds The bounds object to test
1415
+ * @param {int} bounds.left The leftmost value
1416
+ * @param {int} bounds.right The righttmost value
1417
+ * @param {int} bounds.top The topmost value
1418
+ * @param {int} bounds.bottom The bottommost value
1419
+ */
1420
+ function isInBounds(point, bounds) {
1421
+ return (point.x > bounds.left && point.x < bounds.right && point.y > bounds.top && point.y < bounds.bottom);
1422
+ };
1423
+
1424
+
1425
+ }
1426
+
1427
+
1428
+
1429
+
1430
+ /**
1431
+ * A catch all handler that is triggered for all swipe directions.
1432
+ * @name $.fn.swipe#swipe
1433
+ * @event
1434
+ * @default null
1435
+ * @param {EventObject} event The original event object
1436
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1437
+ * @param {int} distance The distance the user swiped
1438
+ * @param {int} duration The duration of the swipe in milliseconds
1439
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1440
+ */
1441
+
1442
+
1443
+
1444
+
1445
+ /**
1446
+ * A handler that is triggered for "left" swipes.
1447
+ * @name $.fn.swipe#swipeLeft
1448
+ * @event
1449
+ * @default null
1450
+ * @param {EventObject} event The original event object
1451
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1452
+ * @param {int} distance The distance the user swiped
1453
+ * @param {int} duration The duration of the swipe in milliseconds
1454
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1455
+ */
1456
+
1457
+ /**
1458
+ * A handler that is triggered for "right" swipes.
1459
+ * @name $.fn.swipe#swipeRight
1460
+ * @event
1461
+ * @default null
1462
+ * @param {EventObject} event The original event object
1463
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1464
+ * @param {int} distance The distance the user swiped
1465
+ * @param {int} duration The duration of the swipe in milliseconds
1466
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1467
+ */
1468
+
1469
+ /**
1470
+ * A handler that is triggered for "up" swipes.
1471
+ * @name $.fn.swipe#swipeUp
1472
+ * @event
1473
+ * @default null
1474
+ * @param {EventObject} event The original event object
1475
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1476
+ * @param {int} distance The distance the user swiped
1477
+ * @param {int} duration The duration of the swipe in milliseconds
1478
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1479
+ */
1480
+
1481
+ /**
1482
+ * A handler that is triggered for "down" swipes.
1483
+ * @name $.fn.swipe#swipeDown
1484
+ * @event
1485
+ * @default null
1486
+ * @param {EventObject} event The original event object
1487
+ * @param {int} direction The direction the user swiped in. See {@link $.fn.swipe.directions}
1488
+ * @param {int} distance The distance the user swiped
1489
+ * @param {int} duration The duration of the swipe in milliseconds
1490
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1491
+ */
1492
+
1493
+ /**
1494
+ * A handler triggered for every phase of the swipe. This handler is constantly fired for the duration of the pinch.
1495
+ * This is triggered regardless of swipe thresholds.
1496
+ * @name $.fn.swipe#swipeStatus
1497
+ * @event
1498
+ * @default null
1499
+ * @param {EventObject} event The original event object
1500
+ * @param {string} phase The phase of the swipe event. See {@link $.fn.swipe.phases}
1501
+ * @param {string} direction The direction the user swiped in. This is null if the user has yet to move. See {@link $.fn.swipe.directions}
1502
+ * @param {int} distance The distance the user swiped. This is 0 if the user has yet to move.
1503
+ * @param {int} duration The duration of the swipe in milliseconds
1504
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1505
+ */
1506
+
1507
+ /**
1508
+ * A handler triggered for pinch in events.
1509
+ * @name $.fn.swipe#pinchIn
1510
+ * @event
1511
+ * @default null
1512
+ * @param {EventObject} event The original event object
1513
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
1514
+ * @param {int} distance The distance the user pinched
1515
+ * @param {int} duration The duration of the swipe in milliseconds
1516
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1517
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
1518
+ */
1519
+
1520
+ /**
1521
+ * A handler triggered for pinch out events.
1522
+ * @name $.fn.swipe#pinchOut
1523
+ * @event
1524
+ * @default null
1525
+ * @param {EventObject} event The original event object
1526
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
1527
+ * @param {int} distance The distance the user pinched
1528
+ * @param {int} duration The duration of the swipe in milliseconds
1529
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1530
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
1531
+ */
1532
+
1533
+ /**
1534
+ * A handler triggered for all pinch events. This handler is constantly fired for the duration of the pinch. This is triggered regardless of thresholds.
1535
+ * @name $.fn.swipe#pinchStatus
1536
+ * @event
1537
+ * @default null
1538
+ * @param {EventObject} event The original event object
1539
+ * @param {int} direction The direction the user pinched in. See {@link $.fn.swipe.directions}
1540
+ * @param {int} distance The distance the user pinched
1541
+ * @param {int} duration The duration of the swipe in milliseconds
1542
+ * @param {int} fingerCount The number of fingers used. See {@link $.fn.swipe.fingers}
1543
+ * @param {int} zoom The zoom/scale level the user pinched too, 0-1.
1544
+ */
1545
+
1546
+ /**
1547
+ * A click handler triggered when a user simply clicks, rather than swipes on an element.
1548
+ * @name $.fn.swipe#click
1549
+ * @event
1550
+ * @default null
1551
+ * @param {EventObject} event The original event object
1552
+ * @param {DomObject} target The element clicked on.
1553
+ */
1554
+
1555
+ })(jQuery);