hourglass 0.0.3.pre

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (802) hide show
  1. data/.document +5 -0
  2. data/Gemfile +18 -0
  3. data/Gemfile.lock +62 -0
  4. data/Guardfile +6 -0
  5. data/LICENSE.txt +20 -0
  6. data/README.rdoc +19 -0
  7. data/Rakefile +111 -0
  8. data/VERSION +1 -0
  9. data/bin/hourglass +7 -0
  10. data/db/.gitignore +3 -0
  11. data/db/migrate/001_create_projects.rb +8 -0
  12. data/db/migrate/002_create_activity.rb +11 -0
  13. data/db/migrate/003_create_settings.rb +10 -0
  14. data/db/migrate/004_create_tags.rb +12 -0
  15. data/hourglass.gemspec +877 -0
  16. data/lib/hourglass.rb +73 -0
  17. data/lib/hourglass/activity.rb +284 -0
  18. data/lib/hourglass/application.rb +134 -0
  19. data/lib/hourglass/database.rb +26 -0
  20. data/lib/hourglass/project.rb +5 -0
  21. data/lib/hourglass/runner.rb +27 -0
  22. data/lib/hourglass/setting.rb +4 -0
  23. data/lib/hourglass/tag.rb +4 -0
  24. data/log/.gitignore +1 -0
  25. data/public/css/base/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  26. data/public/css/base/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  27. data/public/css/base/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  28. data/public/css/base/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  29. data/public/css/base/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  30. data/public/css/base/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  31. data/public/css/base/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  32. data/public/css/base/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  33. data/public/css/base/images/ui-icons_222222_256x240.png +0 -0
  34. data/public/css/base/images/ui-icons_2e83ff_256x240.png +0 -0
  35. data/public/css/base/images/ui-icons_454545_256x240.png +0 -0
  36. data/public/css/base/images/ui-icons_888888_256x240.png +0 -0
  37. data/public/css/base/images/ui-icons_cd0a0a_256x240.png +0 -0
  38. data/public/css/base/jquery-ui.css +563 -0
  39. data/public/css/base/jquery.ui.accordion.css +19 -0
  40. data/public/css/base/jquery.ui.all.css +11 -0
  41. data/public/css/base/jquery.ui.autocomplete.css +53 -0
  42. data/public/css/base/jquery.ui.base.css +21 -0
  43. data/public/css/base/jquery.ui.button.css +38 -0
  44. data/public/css/base/jquery.ui.core.css +38 -0
  45. data/public/css/base/jquery.ui.datepicker.css +68 -0
  46. data/public/css/base/jquery.ui.dialog.css +21 -0
  47. data/public/css/base/jquery.ui.progressbar.css +11 -0
  48. data/public/css/base/jquery.ui.resizable.css +20 -0
  49. data/public/css/base/jquery.ui.selectable.css +10 -0
  50. data/public/css/base/jquery.ui.slider.css +24 -0
  51. data/public/css/base/jquery.ui.tabs.css +18 -0
  52. data/public/css/base/jquery.ui.theme.css +247 -0
  53. data/public/css/base/minified/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  54. data/public/css/base/minified/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  55. data/public/css/base/minified/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  56. data/public/css/base/minified/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  57. data/public/css/base/minified/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  58. data/public/css/base/minified/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  59. data/public/css/base/minified/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  60. data/public/css/base/minified/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  61. data/public/css/base/minified/images/ui-icons_222222_256x240.png +0 -0
  62. data/public/css/base/minified/images/ui-icons_2e83ff_256x240.png +0 -0
  63. data/public/css/base/minified/images/ui-icons_454545_256x240.png +0 -0
  64. data/public/css/base/minified/images/ui-icons_888888_256x240.png +0 -0
  65. data/public/css/base/minified/images/ui-icons_cd0a0a_256x240.png +0 -0
  66. data/public/css/base/minified/jquery-ui.min.css +10 -0
  67. data/public/css/base/minified/jquery.ui.accordion.min.css +10 -0
  68. data/public/css/base/minified/jquery.ui.all.min.css +10 -0
  69. data/public/css/base/minified/jquery.ui.autocomplete.min.css +10 -0
  70. data/public/css/base/minified/jquery.ui.base.min.css +10 -0
  71. data/public/css/base/minified/jquery.ui.button.min.css +10 -0
  72. data/public/css/base/minified/jquery.ui.core.min.css +10 -0
  73. data/public/css/base/minified/jquery.ui.datepicker.min.css +10 -0
  74. data/public/css/base/minified/jquery.ui.dialog.min.css +10 -0
  75. data/public/css/base/minified/jquery.ui.progressbar.min.css +10 -0
  76. data/public/css/base/minified/jquery.ui.resizable.min.css +10 -0
  77. data/public/css/base/minified/jquery.ui.selectable.min.css +10 -0
  78. data/public/css/base/minified/jquery.ui.slider.min.css +10 -0
  79. data/public/css/base/minified/jquery.ui.tabs.min.css +10 -0
  80. data/public/css/base/minified/jquery.ui.theme.min.css +12 -0
  81. data/public/css/black-tie/images/ui-bg_diagonals-thick_8_333333_40x40.png +0 -0
  82. data/public/css/black-tie/images/ui-bg_flat_65_ffffff_40x100.png +0 -0
  83. data/public/css/black-tie/images/ui-bg_glass_40_111111_1x400.png +0 -0
  84. data/public/css/black-tie/images/ui-bg_glass_55_1c1c1c_1x400.png +0 -0
  85. data/public/css/black-tie/images/ui-bg_highlight-hard_100_f9f9f9_1x100.png +0 -0
  86. data/public/css/black-tie/images/ui-bg_highlight-hard_40_aaaaaa_1x100.png +0 -0
  87. data/public/css/black-tie/images/ui-bg_highlight-soft_50_aaaaaa_1x100.png +0 -0
  88. data/public/css/black-tie/images/ui-bg_inset-hard_45_cd0a0a_1x100.png +0 -0
  89. data/public/css/black-tie/images/ui-bg_inset-hard_55_ffeb80_1x100.png +0 -0
  90. data/public/css/black-tie/images/ui-icons_222222_256x240.png +0 -0
  91. data/public/css/black-tie/images/ui-icons_4ca300_256x240.png +0 -0
  92. data/public/css/black-tie/images/ui-icons_bbbbbb_256x240.png +0 -0
  93. data/public/css/black-tie/images/ui-icons_ededed_256x240.png +0 -0
  94. data/public/css/black-tie/images/ui-icons_ffcf29_256x240.png +0 -0
  95. data/public/css/black-tie/images/ui-icons_ffffff_256x240.png +0 -0
  96. data/public/css/black-tie/jquery-ui.css +565 -0
  97. data/public/css/black-tie/jquery.ui.accordion.css +19 -0
  98. data/public/css/black-tie/jquery.ui.all.css +11 -0
  99. data/public/css/black-tie/jquery.ui.autocomplete.css +53 -0
  100. data/public/css/black-tie/jquery.ui.base.css +11 -0
  101. data/public/css/black-tie/jquery.ui.button.css +38 -0
  102. data/public/css/black-tie/jquery.ui.core.css +38 -0
  103. data/public/css/black-tie/jquery.ui.datepicker.css +68 -0
  104. data/public/css/black-tie/jquery.ui.dialog.css +21 -0
  105. data/public/css/black-tie/jquery.ui.progressbar.css +11 -0
  106. data/public/css/black-tie/jquery.ui.resizable.css +20 -0
  107. data/public/css/black-tie/jquery.ui.selectable.css +10 -0
  108. data/public/css/black-tie/jquery.ui.slider.css +24 -0
  109. data/public/css/black-tie/jquery.ui.tabs.css +18 -0
  110. data/public/css/black-tie/jquery.ui.theme.css +249 -0
  111. data/public/css/blitzer/images/ui-bg_diagonals-thick_75_f3d8d8_40x40.png +0 -0
  112. data/public/css/blitzer/images/ui-bg_dots-small_65_a6a6a6_2x2.png +0 -0
  113. data/public/css/blitzer/images/ui-bg_flat_0_333333_40x100.png +0 -0
  114. data/public/css/blitzer/images/ui-bg_flat_65_ffffff_40x100.png +0 -0
  115. data/public/css/blitzer/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  116. data/public/css/blitzer/images/ui-bg_glass_55_fbf8ee_1x400.png +0 -0
  117. data/public/css/blitzer/images/ui-bg_highlight-hard_100_eeeeee_1x100.png +0 -0
  118. data/public/css/blitzer/images/ui-bg_highlight-hard_100_f6f6f6_1x100.png +0 -0
  119. data/public/css/blitzer/images/ui-bg_highlight-soft_15_cc0000_1x100.png +0 -0
  120. data/public/css/blitzer/images/ui-icons_004276_256x240.png +0 -0
  121. data/public/css/blitzer/images/ui-icons_cc0000_256x240.png +0 -0
  122. data/public/css/blitzer/images/ui-icons_ffffff_256x240.png +0 -0
  123. data/public/css/blitzer/jquery-ui.css +565 -0
  124. data/public/css/blitzer/jquery.ui.accordion.css +19 -0
  125. data/public/css/blitzer/jquery.ui.all.css +11 -0
  126. data/public/css/blitzer/jquery.ui.autocomplete.css +53 -0
  127. data/public/css/blitzer/jquery.ui.base.css +11 -0
  128. data/public/css/blitzer/jquery.ui.button.css +38 -0
  129. data/public/css/blitzer/jquery.ui.core.css +38 -0
  130. data/public/css/blitzer/jquery.ui.datepicker.css +68 -0
  131. data/public/css/blitzer/jquery.ui.dialog.css +21 -0
  132. data/public/css/blitzer/jquery.ui.progressbar.css +11 -0
  133. data/public/css/blitzer/jquery.ui.resizable.css +20 -0
  134. data/public/css/blitzer/jquery.ui.selectable.css +10 -0
  135. data/public/css/blitzer/jquery.ui.slider.css +24 -0
  136. data/public/css/blitzer/jquery.ui.tabs.css +18 -0
  137. data/public/css/blitzer/jquery.ui.theme.css +249 -0
  138. data/public/css/cupertino/images/ui-bg_diagonals-thick_90_eeeeee_40x40.png +0 -0
  139. data/public/css/cupertino/images/ui-bg_flat_15_cd0a0a_40x100.png +0 -0
  140. data/public/css/cupertino/images/ui-bg_glass_100_e4f1fb_1x400.png +0 -0
  141. data/public/css/cupertino/images/ui-bg_glass_50_3baae3_1x400.png +0 -0
  142. data/public/css/cupertino/images/ui-bg_glass_80_d7ebf9_1x400.png +0 -0
  143. data/public/css/cupertino/images/ui-bg_highlight-hard_100_f2f5f7_1x100.png +0 -0
  144. data/public/css/cupertino/images/ui-bg_highlight-hard_70_000000_1x100.png +0 -0
  145. data/public/css/cupertino/images/ui-bg_highlight-soft_100_deedf7_1x100.png +0 -0
  146. data/public/css/cupertino/images/ui-bg_highlight-soft_25_ffef8f_1x100.png +0 -0
  147. data/public/css/cupertino/images/ui-icons_2694e8_256x240.png +0 -0
  148. data/public/css/cupertino/images/ui-icons_2e83ff_256x240.png +0 -0
  149. data/public/css/cupertino/images/ui-icons_3d80b3_256x240.png +0 -0
  150. data/public/css/cupertino/images/ui-icons_72a7cf_256x240.png +0 -0
  151. data/public/css/cupertino/images/ui-icons_ffffff_256x240.png +0 -0
  152. data/public/css/cupertino/jquery-ui.css +565 -0
  153. data/public/css/cupertino/jquery.ui.accordion.css +19 -0
  154. data/public/css/cupertino/jquery.ui.all.css +11 -0
  155. data/public/css/cupertino/jquery.ui.autocomplete.css +53 -0
  156. data/public/css/cupertino/jquery.ui.base.css +11 -0
  157. data/public/css/cupertino/jquery.ui.button.css +38 -0
  158. data/public/css/cupertino/jquery.ui.core.css +38 -0
  159. data/public/css/cupertino/jquery.ui.datepicker.css +68 -0
  160. data/public/css/cupertino/jquery.ui.dialog.css +21 -0
  161. data/public/css/cupertino/jquery.ui.progressbar.css +11 -0
  162. data/public/css/cupertino/jquery.ui.resizable.css +20 -0
  163. data/public/css/cupertino/jquery.ui.selectable.css +10 -0
  164. data/public/css/cupertino/jquery.ui.slider.css +24 -0
  165. data/public/css/cupertino/jquery.ui.tabs.css +18 -0
  166. data/public/css/cupertino/jquery.ui.theme.css +249 -0
  167. data/public/css/dark-hive/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
  168. data/public/css/dark-hive/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
  169. data/public/css/dark-hive/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
  170. data/public/css/dark-hive/images/ui-bg_highlight-hard_20_0972a5_1x100.png +0 -0
  171. data/public/css/dark-hive/images/ui-bg_highlight-soft_33_003147_1x100.png +0 -0
  172. data/public/css/dark-hive/images/ui-bg_highlight-soft_35_222222_1x100.png +0 -0
  173. data/public/css/dark-hive/images/ui-bg_highlight-soft_44_444444_1x100.png +0 -0
  174. data/public/css/dark-hive/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
  175. data/public/css/dark-hive/images/ui-bg_loop_25_000000_21x21.png +0 -0
  176. data/public/css/dark-hive/images/ui-icons_222222_256x240.png +0 -0
  177. data/public/css/dark-hive/images/ui-icons_4b8e0b_256x240.png +0 -0
  178. data/public/css/dark-hive/images/ui-icons_a83300_256x240.png +0 -0
  179. data/public/css/dark-hive/images/ui-icons_cccccc_256x240.png +0 -0
  180. data/public/css/dark-hive/images/ui-icons_ffffff_256x240.png +0 -0
  181. data/public/css/dark-hive/jquery-ui.css +565 -0
  182. data/public/css/dark-hive/jquery.ui.accordion.css +19 -0
  183. data/public/css/dark-hive/jquery.ui.all.css +11 -0
  184. data/public/css/dark-hive/jquery.ui.autocomplete.css +53 -0
  185. data/public/css/dark-hive/jquery.ui.base.css +11 -0
  186. data/public/css/dark-hive/jquery.ui.button.css +38 -0
  187. data/public/css/dark-hive/jquery.ui.core.css +38 -0
  188. data/public/css/dark-hive/jquery.ui.datepicker.css +68 -0
  189. data/public/css/dark-hive/jquery.ui.dialog.css +21 -0
  190. data/public/css/dark-hive/jquery.ui.progressbar.css +11 -0
  191. data/public/css/dark-hive/jquery.ui.resizable.css +20 -0
  192. data/public/css/dark-hive/jquery.ui.selectable.css +10 -0
  193. data/public/css/dark-hive/jquery.ui.slider.css +24 -0
  194. data/public/css/dark-hive/jquery.ui.tabs.css +18 -0
  195. data/public/css/dark-hive/jquery.ui.theme.css +249 -0
  196. data/public/css/dot-luv/images/ui-bg_diagonals-thick_15_0b3e6f_40x40.png +0 -0
  197. data/public/css/dot-luv/images/ui-bg_dots-medium_30_0b58a2_4x4.png +0 -0
  198. data/public/css/dot-luv/images/ui-bg_dots-small_20_333333_2x2.png +0 -0
  199. data/public/css/dot-luv/images/ui-bg_dots-small_30_a32d00_2x2.png +0 -0
  200. data/public/css/dot-luv/images/ui-bg_dots-small_40_00498f_2x2.png +0 -0
  201. data/public/css/dot-luv/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  202. data/public/css/dot-luv/images/ui-bg_flat_40_292929_40x100.png +0 -0
  203. data/public/css/dot-luv/images/ui-bg_gloss-wave_20_111111_500x100.png +0 -0
  204. data/public/css/dot-luv/images/ui-icons_00498f_256x240.png +0 -0
  205. data/public/css/dot-luv/images/ui-icons_98d2fb_256x240.png +0 -0
  206. data/public/css/dot-luv/images/ui-icons_9ccdfc_256x240.png +0 -0
  207. data/public/css/dot-luv/images/ui-icons_ffffff_256x240.png +0 -0
  208. data/public/css/dot-luv/jquery-ui.css +565 -0
  209. data/public/css/dot-luv/jquery.ui.accordion.css +19 -0
  210. data/public/css/dot-luv/jquery.ui.all.css +11 -0
  211. data/public/css/dot-luv/jquery.ui.autocomplete.css +53 -0
  212. data/public/css/dot-luv/jquery.ui.base.css +11 -0
  213. data/public/css/dot-luv/jquery.ui.button.css +38 -0
  214. data/public/css/dot-luv/jquery.ui.core.css +38 -0
  215. data/public/css/dot-luv/jquery.ui.datepicker.css +68 -0
  216. data/public/css/dot-luv/jquery.ui.dialog.css +21 -0
  217. data/public/css/dot-luv/jquery.ui.progressbar.css +11 -0
  218. data/public/css/dot-luv/jquery.ui.resizable.css +20 -0
  219. data/public/css/dot-luv/jquery.ui.selectable.css +10 -0
  220. data/public/css/dot-luv/jquery.ui.slider.css +24 -0
  221. data/public/css/dot-luv/jquery.ui.tabs.css +18 -0
  222. data/public/css/dot-luv/jquery.ui.theme.css +249 -0
  223. data/public/css/eggplant/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  224. data/public/css/eggplant/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  225. data/public/css/eggplant/images/ui-bg_flat_55_994d53_40x100.png +0 -0
  226. data/public/css/eggplant/images/ui-bg_flat_55_fafafa_40x100.png +0 -0
  227. data/public/css/eggplant/images/ui-bg_gloss-wave_30_3d3644_500x100.png +0 -0
  228. data/public/css/eggplant/images/ui-bg_highlight-soft_100_dcd9de_1x100.png +0 -0
  229. data/public/css/eggplant/images/ui-bg_highlight-soft_100_eae6ea_1x100.png +0 -0
  230. data/public/css/eggplant/images/ui-bg_highlight-soft_25_30273a_1x100.png +0 -0
  231. data/public/css/eggplant/images/ui-bg_highlight-soft_45_5f5964_1x100.png +0 -0
  232. data/public/css/eggplant/images/ui-icons_454545_256x240.png +0 -0
  233. data/public/css/eggplant/images/ui-icons_734d99_256x240.png +0 -0
  234. data/public/css/eggplant/images/ui-icons_8d78a5_256x240.png +0 -0
  235. data/public/css/eggplant/images/ui-icons_a8a3ae_256x240.png +0 -0
  236. data/public/css/eggplant/images/ui-icons_ebccce_256x240.png +0 -0
  237. data/public/css/eggplant/images/ui-icons_ffffff_256x240.png +0 -0
  238. data/public/css/eggplant/jquery-ui.css +565 -0
  239. data/public/css/eggplant/jquery.ui.accordion.css +19 -0
  240. data/public/css/eggplant/jquery.ui.all.css +11 -0
  241. data/public/css/eggplant/jquery.ui.autocomplete.css +53 -0
  242. data/public/css/eggplant/jquery.ui.base.css +11 -0
  243. data/public/css/eggplant/jquery.ui.button.css +38 -0
  244. data/public/css/eggplant/jquery.ui.core.css +38 -0
  245. data/public/css/eggplant/jquery.ui.datepicker.css +68 -0
  246. data/public/css/eggplant/jquery.ui.dialog.css +21 -0
  247. data/public/css/eggplant/jquery.ui.progressbar.css +11 -0
  248. data/public/css/eggplant/jquery.ui.resizable.css +20 -0
  249. data/public/css/eggplant/jquery.ui.selectable.css +10 -0
  250. data/public/css/eggplant/jquery.ui.slider.css +24 -0
  251. data/public/css/eggplant/jquery.ui.tabs.css +18 -0
  252. data/public/css/eggplant/jquery.ui.theme.css +249 -0
  253. data/public/css/excite-bike/images/ui-bg_diagonals-small_25_c5ddfc_40x40.png +0 -0
  254. data/public/css/excite-bike/images/ui-bg_diagonals-thick_20_e69700_40x40.png +0 -0
  255. data/public/css/excite-bike/images/ui-bg_diagonals-thick_22_1484e6_40x40.png +0 -0
  256. data/public/css/excite-bike/images/ui-bg_diagonals-thick_26_2293f7_40x40.png +0 -0
  257. data/public/css/excite-bike/images/ui-bg_flat_0_e69700_40x100.png +0 -0
  258. data/public/css/excite-bike/images/ui-bg_flat_0_e6b900_40x100.png +0 -0
  259. data/public/css/excite-bike/images/ui-bg_highlight-soft_100_f9f9f9_1x100.png +0 -0
  260. data/public/css/excite-bike/images/ui-bg_inset-hard_100_eeeeee_1x100.png +0 -0
  261. data/public/css/excite-bike/images/ui-icons_0a82eb_256x240.png +0 -0
  262. data/public/css/excite-bike/images/ui-icons_0b54d5_256x240.png +0 -0
  263. data/public/css/excite-bike/images/ui-icons_5fa5e3_256x240.png +0 -0
  264. data/public/css/excite-bike/images/ui-icons_fcdd4a_256x240.png +0 -0
  265. data/public/css/excite-bike/images/ui-icons_ffffff_256x240.png +0 -0
  266. data/public/css/excite-bike/jquery-ui.css +565 -0
  267. data/public/css/excite-bike/jquery.ui.accordion.css +19 -0
  268. data/public/css/excite-bike/jquery.ui.all.css +11 -0
  269. data/public/css/excite-bike/jquery.ui.autocomplete.css +53 -0
  270. data/public/css/excite-bike/jquery.ui.base.css +11 -0
  271. data/public/css/excite-bike/jquery.ui.button.css +38 -0
  272. data/public/css/excite-bike/jquery.ui.core.css +38 -0
  273. data/public/css/excite-bike/jquery.ui.datepicker.css +68 -0
  274. data/public/css/excite-bike/jquery.ui.dialog.css +21 -0
  275. data/public/css/excite-bike/jquery.ui.progressbar.css +11 -0
  276. data/public/css/excite-bike/jquery.ui.resizable.css +20 -0
  277. data/public/css/excite-bike/jquery.ui.selectable.css +10 -0
  278. data/public/css/excite-bike/jquery.ui.slider.css +24 -0
  279. data/public/css/excite-bike/jquery.ui.tabs.css +18 -0
  280. data/public/css/excite-bike/jquery.ui.theme.css +249 -0
  281. data/public/css/flick/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  282. data/public/css/flick/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  283. data/public/css/flick/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  284. data/public/css/flick/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  285. data/public/css/flick/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  286. data/public/css/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  287. data/public/css/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  288. data/public/css/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  289. data/public/css/flick/images/ui-icons_0073ea_256x240.png +0 -0
  290. data/public/css/flick/images/ui-icons_454545_256x240.png +0 -0
  291. data/public/css/flick/images/ui-icons_666666_256x240.png +0 -0
  292. data/public/css/flick/images/ui-icons_ff0084_256x240.png +0 -0
  293. data/public/css/flick/images/ui-icons_ffffff_256x240.png +0 -0
  294. data/public/css/flick/jquery-ui.css +565 -0
  295. data/public/css/flick/jquery.ui.accordion.css +19 -0
  296. data/public/css/flick/jquery.ui.all.css +11 -0
  297. data/public/css/flick/jquery.ui.autocomplete.css +53 -0
  298. data/public/css/flick/jquery.ui.base.css +11 -0
  299. data/public/css/flick/jquery.ui.button.css +38 -0
  300. data/public/css/flick/jquery.ui.core.css +38 -0
  301. data/public/css/flick/jquery.ui.datepicker.css +68 -0
  302. data/public/css/flick/jquery.ui.dialog.css +21 -0
  303. data/public/css/flick/jquery.ui.progressbar.css +11 -0
  304. data/public/css/flick/jquery.ui.resizable.css +20 -0
  305. data/public/css/flick/jquery.ui.selectable.css +10 -0
  306. data/public/css/flick/jquery.ui.slider.css +24 -0
  307. data/public/css/flick/jquery.ui.tabs.css +18 -0
  308. data/public/css/flick/jquery.ui.theme.css +249 -0
  309. data/public/css/hot-sneaks/images/ui-bg_diagonals-small_40_db4865_40x40.png +0 -0
  310. data/public/css/hot-sneaks/images/ui-bg_diagonals-small_50_93c3cd_40x40.png +0 -0
  311. data/public/css/hot-sneaks/images/ui-bg_diagonals-small_50_ff3853_40x40.png +0 -0
  312. data/public/css/hot-sneaks/images/ui-bg_diagonals-small_75_ccd232_40x40.png +0 -0
  313. data/public/css/hot-sneaks/images/ui-bg_dots-medium_80_ffff38_4x4.png +0 -0
  314. data/public/css/hot-sneaks/images/ui-bg_dots-small_35_35414f_2x2.png +0 -0
  315. data/public/css/hot-sneaks/images/ui-bg_flat_75_ba9217_40x100.png +0 -0
  316. data/public/css/hot-sneaks/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  317. data/public/css/hot-sneaks/images/ui-bg_white-lines_85_f7f7ba_40x100.png +0 -0
  318. data/public/css/hot-sneaks/images/ui-icons_454545_256x240.png +0 -0
  319. data/public/css/hot-sneaks/images/ui-icons_88a206_256x240.png +0 -0
  320. data/public/css/hot-sneaks/images/ui-icons_c02669_256x240.png +0 -0
  321. data/public/css/hot-sneaks/images/ui-icons_e1e463_256x240.png +0 -0
  322. data/public/css/hot-sneaks/images/ui-icons_ffeb33_256x240.png +0 -0
  323. data/public/css/hot-sneaks/images/ui-icons_ffffff_256x240.png +0 -0
  324. data/public/css/hot-sneaks/jquery-ui.css +565 -0
  325. data/public/css/hot-sneaks/jquery.ui.accordion.css +19 -0
  326. data/public/css/hot-sneaks/jquery.ui.all.css +11 -0
  327. data/public/css/hot-sneaks/jquery.ui.autocomplete.css +53 -0
  328. data/public/css/hot-sneaks/jquery.ui.base.css +11 -0
  329. data/public/css/hot-sneaks/jquery.ui.button.css +38 -0
  330. data/public/css/hot-sneaks/jquery.ui.core.css +38 -0
  331. data/public/css/hot-sneaks/jquery.ui.datepicker.css +68 -0
  332. data/public/css/hot-sneaks/jquery.ui.dialog.css +21 -0
  333. data/public/css/hot-sneaks/jquery.ui.progressbar.css +11 -0
  334. data/public/css/hot-sneaks/jquery.ui.resizable.css +20 -0
  335. data/public/css/hot-sneaks/jquery.ui.selectable.css +10 -0
  336. data/public/css/hot-sneaks/jquery.ui.slider.css +24 -0
  337. data/public/css/hot-sneaks/jquery.ui.tabs.css +18 -0
  338. data/public/css/hot-sneaks/jquery.ui.theme.css +249 -0
  339. data/public/css/humanity/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
  340. data/public/css/humanity/images/ui-bg_glass_100_f5f0e5_1x400.png +0 -0
  341. data/public/css/humanity/images/ui-bg_glass_25_cb842e_1x400.png +0 -0
  342. data/public/css/humanity/images/ui-bg_glass_70_ede4d4_1x400.png +0 -0
  343. data/public/css/humanity/images/ui-bg_highlight-hard_100_f4f0ec_1x100.png +0 -0
  344. data/public/css/humanity/images/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
  345. data/public/css/humanity/images/ui-bg_highlight-hard_75_f5f5b5_1x100.png +0 -0
  346. data/public/css/humanity/images/ui-bg_inset-soft_100_f4f0ec_1x100.png +0 -0
  347. data/public/css/humanity/images/ui-icons_c47a23_256x240.png +0 -0
  348. data/public/css/humanity/images/ui-icons_cb672b_256x240.png +0 -0
  349. data/public/css/humanity/images/ui-icons_f08000_256x240.png +0 -0
  350. data/public/css/humanity/images/ui-icons_f35f07_256x240.png +0 -0
  351. data/public/css/humanity/images/ui-icons_ff7519_256x240.png +0 -0
  352. data/public/css/humanity/images/ui-icons_ffffff_256x240.png +0 -0
  353. data/public/css/humanity/jquery-ui.css +565 -0
  354. data/public/css/humanity/jquery.ui.accordion.css +19 -0
  355. data/public/css/humanity/jquery.ui.all.css +11 -0
  356. data/public/css/humanity/jquery.ui.autocomplete.css +53 -0
  357. data/public/css/humanity/jquery.ui.base.css +11 -0
  358. data/public/css/humanity/jquery.ui.button.css +38 -0
  359. data/public/css/humanity/jquery.ui.core.css +38 -0
  360. data/public/css/humanity/jquery.ui.datepicker.css +68 -0
  361. data/public/css/humanity/jquery.ui.dialog.css +21 -0
  362. data/public/css/humanity/jquery.ui.progressbar.css +11 -0
  363. data/public/css/humanity/jquery.ui.resizable.css +20 -0
  364. data/public/css/humanity/jquery.ui.selectable.css +10 -0
  365. data/public/css/humanity/jquery.ui.slider.css +24 -0
  366. data/public/css/humanity/jquery.ui.tabs.css +18 -0
  367. data/public/css/humanity/jquery.ui.theme.css +249 -0
  368. data/public/css/le-frog/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png +0 -0
  369. data/public/css/le-frog/images/ui-bg_diagonals-thick_15_444444_40x40.png +0 -0
  370. data/public/css/le-frog/images/ui-bg_diagonals-thick_95_ffdc2e_40x40.png +0 -0
  371. data/public/css/le-frog/images/ui-bg_glass_55_fbf5d0_1x400.png +0 -0
  372. data/public/css/le-frog/images/ui-bg_highlight-hard_30_285c00_1x100.png +0 -0
  373. data/public/css/le-frog/images/ui-bg_highlight-soft_33_3a8104_1x100.png +0 -0
  374. data/public/css/le-frog/images/ui-bg_highlight-soft_50_4eb305_1x100.png +0 -0
  375. data/public/css/le-frog/images/ui-bg_highlight-soft_60_4ca20b_1x100.png +0 -0
  376. data/public/css/le-frog/images/ui-bg_inset-soft_10_285c00_1x100.png +0 -0
  377. data/public/css/le-frog/images/ui-icons_4eb305_256x240.png +0 -0
  378. data/public/css/le-frog/images/ui-icons_72b42d_256x240.png +0 -0
  379. data/public/css/le-frog/images/ui-icons_cd0a0a_256x240.png +0 -0
  380. data/public/css/le-frog/images/ui-icons_ffffff_256x240.png +0 -0
  381. data/public/css/le-frog/jquery-ui.css +565 -0
  382. data/public/css/le-frog/jquery.ui.accordion.css +19 -0
  383. data/public/css/le-frog/jquery.ui.all.css +11 -0
  384. data/public/css/le-frog/jquery.ui.autocomplete.css +53 -0
  385. data/public/css/le-frog/jquery.ui.base.css +11 -0
  386. data/public/css/le-frog/jquery.ui.button.css +38 -0
  387. data/public/css/le-frog/jquery.ui.core.css +38 -0
  388. data/public/css/le-frog/jquery.ui.datepicker.css +68 -0
  389. data/public/css/le-frog/jquery.ui.dialog.css +21 -0
  390. data/public/css/le-frog/jquery.ui.progressbar.css +11 -0
  391. data/public/css/le-frog/jquery.ui.resizable.css +20 -0
  392. data/public/css/le-frog/jquery.ui.selectable.css +10 -0
  393. data/public/css/le-frog/jquery.ui.slider.css +24 -0
  394. data/public/css/le-frog/jquery.ui.tabs.css +18 -0
  395. data/public/css/le-frog/jquery.ui.theme.css +249 -0
  396. data/public/css/mint-choc/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  397. data/public/css/mint-choc/images/ui-bg_glass_15_5f391b_1x400.png +0 -0
  398. data/public/css/mint-choc/images/ui-bg_gloss-wave_20_1c160d_500x100.png +0 -0
  399. data/public/css/mint-choc/images/ui-bg_gloss-wave_25_453326_500x100.png +0 -0
  400. data/public/css/mint-choc/images/ui-bg_gloss-wave_30_44372c_500x100.png +0 -0
  401. data/public/css/mint-choc/images/ui-bg_highlight-soft_20_201913_1x100.png +0 -0
  402. data/public/css/mint-choc/images/ui-bg_highlight-soft_20_619226_1x100.png +0 -0
  403. data/public/css/mint-choc/images/ui-bg_inset-soft_10_201913_1x100.png +0 -0
  404. data/public/css/mint-choc/images/ui-icons_222222_256x240.png +0 -0
  405. data/public/css/mint-choc/images/ui-icons_9bcc60_256x240.png +0 -0
  406. data/public/css/mint-choc/images/ui-icons_add978_256x240.png +0 -0
  407. data/public/css/mint-choc/images/ui-icons_e3ddc9_256x240.png +0 -0
  408. data/public/css/mint-choc/images/ui-icons_f1fd86_256x240.png +0 -0
  409. data/public/css/mint-choc/images/ui-icons_ffffff_256x240.png +0 -0
  410. data/public/css/mint-choc/jquery-ui.css +565 -0
  411. data/public/css/mint-choc/jquery.ui.accordion.css +19 -0
  412. data/public/css/mint-choc/jquery.ui.all.css +11 -0
  413. data/public/css/mint-choc/jquery.ui.autocomplete.css +53 -0
  414. data/public/css/mint-choc/jquery.ui.base.css +11 -0
  415. data/public/css/mint-choc/jquery.ui.button.css +38 -0
  416. data/public/css/mint-choc/jquery.ui.core.css +38 -0
  417. data/public/css/mint-choc/jquery.ui.datepicker.css +68 -0
  418. data/public/css/mint-choc/jquery.ui.dialog.css +21 -0
  419. data/public/css/mint-choc/jquery.ui.progressbar.css +11 -0
  420. data/public/css/mint-choc/jquery.ui.resizable.css +20 -0
  421. data/public/css/mint-choc/jquery.ui.selectable.css +10 -0
  422. data/public/css/mint-choc/jquery.ui.slider.css +24 -0
  423. data/public/css/mint-choc/jquery.ui.tabs.css +18 -0
  424. data/public/css/mint-choc/jquery.ui.theme.css +249 -0
  425. data/public/css/overcast/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  426. data/public/css/overcast/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  427. data/public/css/overcast/images/ui-bg_flat_55_c0402a_40x100.png +0 -0
  428. data/public/css/overcast/images/ui-bg_flat_55_eeeeee_40x100.png +0 -0
  429. data/public/css/overcast/images/ui-bg_glass_100_f8f8f8_1x400.png +0 -0
  430. data/public/css/overcast/images/ui-bg_glass_35_dddddd_1x400.png +0 -0
  431. data/public/css/overcast/images/ui-bg_glass_60_eeeeee_1x400.png +0 -0
  432. data/public/css/overcast/images/ui-bg_inset-hard_75_999999_1x100.png +0 -0
  433. data/public/css/overcast/images/ui-bg_inset-soft_50_c9c9c9_1x100.png +0 -0
  434. data/public/css/overcast/images/ui-icons_3383bb_256x240.png +0 -0
  435. data/public/css/overcast/images/ui-icons_454545_256x240.png +0 -0
  436. data/public/css/overcast/images/ui-icons_70b2e1_256x240.png +0 -0
  437. data/public/css/overcast/images/ui-icons_999999_256x240.png +0 -0
  438. data/public/css/overcast/images/ui-icons_fbc856_256x240.png +0 -0
  439. data/public/css/overcast/jquery-ui.css +565 -0
  440. data/public/css/overcast/jquery.ui.accordion.css +19 -0
  441. data/public/css/overcast/jquery.ui.all.css +11 -0
  442. data/public/css/overcast/jquery.ui.autocomplete.css +53 -0
  443. data/public/css/overcast/jquery.ui.base.css +11 -0
  444. data/public/css/overcast/jquery.ui.button.css +38 -0
  445. data/public/css/overcast/jquery.ui.core.css +38 -0
  446. data/public/css/overcast/jquery.ui.datepicker.css +68 -0
  447. data/public/css/overcast/jquery.ui.dialog.css +21 -0
  448. data/public/css/overcast/jquery.ui.progressbar.css +11 -0
  449. data/public/css/overcast/jquery.ui.resizable.css +20 -0
  450. data/public/css/overcast/jquery.ui.selectable.css +10 -0
  451. data/public/css/overcast/jquery.ui.slider.css +24 -0
  452. data/public/css/overcast/jquery.ui.tabs.css +18 -0
  453. data/public/css/overcast/jquery.ui.theme.css +249 -0
  454. data/public/css/pepper-grinder/images/ui-bg_diagonal-maze_20_6e4f1c_10x10.png +0 -0
  455. data/public/css/pepper-grinder/images/ui-bg_diagonal-maze_40_000000_10x10.png +0 -0
  456. data/public/css/pepper-grinder/images/ui-bg_fine-grain_10_eceadf_60x60.png +0 -0
  457. data/public/css/pepper-grinder/images/ui-bg_fine-grain_10_f8f7f6_60x60.png +0 -0
  458. data/public/css/pepper-grinder/images/ui-bg_fine-grain_15_eceadf_60x60.png +0 -0
  459. data/public/css/pepper-grinder/images/ui-bg_fine-grain_15_f7f3de_60x60.png +0 -0
  460. data/public/css/pepper-grinder/images/ui-bg_fine-grain_15_ffffff_60x60.png +0 -0
  461. data/public/css/pepper-grinder/images/ui-bg_fine-grain_65_654b24_60x60.png +0 -0
  462. data/public/css/pepper-grinder/images/ui-bg_fine-grain_68_b83400_60x60.png +0 -0
  463. data/public/css/pepper-grinder/images/ui-icons_222222_256x240.png +0 -0
  464. data/public/css/pepper-grinder/images/ui-icons_3572ac_256x240.png +0 -0
  465. data/public/css/pepper-grinder/images/ui-icons_8c291d_256x240.png +0 -0
  466. data/public/css/pepper-grinder/images/ui-icons_b83400_256x240.png +0 -0
  467. data/public/css/pepper-grinder/images/ui-icons_fbdb93_256x240.png +0 -0
  468. data/public/css/pepper-grinder/images/ui-icons_ffffff_256x240.png +0 -0
  469. data/public/css/pepper-grinder/jquery-ui.css +565 -0
  470. data/public/css/pepper-grinder/jquery.ui.accordion.css +19 -0
  471. data/public/css/pepper-grinder/jquery.ui.all.css +11 -0
  472. data/public/css/pepper-grinder/jquery.ui.autocomplete.css +53 -0
  473. data/public/css/pepper-grinder/jquery.ui.base.css +11 -0
  474. data/public/css/pepper-grinder/jquery.ui.button.css +38 -0
  475. data/public/css/pepper-grinder/jquery.ui.core.css +38 -0
  476. data/public/css/pepper-grinder/jquery.ui.datepicker.css +68 -0
  477. data/public/css/pepper-grinder/jquery.ui.dialog.css +21 -0
  478. data/public/css/pepper-grinder/jquery.ui.progressbar.css +11 -0
  479. data/public/css/pepper-grinder/jquery.ui.resizable.css +20 -0
  480. data/public/css/pepper-grinder/jquery.ui.selectable.css +10 -0
  481. data/public/css/pepper-grinder/jquery.ui.slider.css +24 -0
  482. data/public/css/pepper-grinder/jquery.ui.tabs.css +18 -0
  483. data/public/css/pepper-grinder/jquery.ui.theme.css +249 -0
  484. data/public/css/redmond/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  485. data/public/css/redmond/images/ui-bg_flat_55_fbec88_40x100.png +0 -0
  486. data/public/css/redmond/images/ui-bg_glass_75_d0e5f5_1x400.png +0 -0
  487. data/public/css/redmond/images/ui-bg_glass_85_dfeffc_1x400.png +0 -0
  488. data/public/css/redmond/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  489. data/public/css/redmond/images/ui-bg_gloss-wave_55_5c9ccc_500x100.png +0 -0
  490. data/public/css/redmond/images/ui-bg_inset-hard_100_f5f8f9_1x100.png +0 -0
  491. data/public/css/redmond/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  492. data/public/css/redmond/images/ui-icons_217bc0_256x240.png +0 -0
  493. data/public/css/redmond/images/ui-icons_2e83ff_256x240.png +0 -0
  494. data/public/css/redmond/images/ui-icons_469bdd_256x240.png +0 -0
  495. data/public/css/redmond/images/ui-icons_6da8d5_256x240.png +0 -0
  496. data/public/css/redmond/images/ui-icons_cd0a0a_256x240.png +0 -0
  497. data/public/css/redmond/images/ui-icons_d8e7f3_256x240.png +0 -0
  498. data/public/css/redmond/images/ui-icons_f9bd01_256x240.png +0 -0
  499. data/public/css/redmond/jquery-ui.css +565 -0
  500. data/public/css/redmond/jquery.ui.accordion.css +19 -0
  501. data/public/css/redmond/jquery.ui.all.css +11 -0
  502. data/public/css/redmond/jquery.ui.autocomplete.css +53 -0
  503. data/public/css/redmond/jquery.ui.base.css +11 -0
  504. data/public/css/redmond/jquery.ui.button.css +38 -0
  505. data/public/css/redmond/jquery.ui.core.css +38 -0
  506. data/public/css/redmond/jquery.ui.datepicker.css +68 -0
  507. data/public/css/redmond/jquery.ui.dialog.css +21 -0
  508. data/public/css/redmond/jquery.ui.progressbar.css +11 -0
  509. data/public/css/redmond/jquery.ui.resizable.css +20 -0
  510. data/public/css/redmond/jquery.ui.selectable.css +10 -0
  511. data/public/css/redmond/jquery.ui.slider.css +24 -0
  512. data/public/css/redmond/jquery.ui.tabs.css +18 -0
  513. data/public/css/redmond/jquery.ui.theme.css +249 -0
  514. data/public/css/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  515. data/public/css/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  516. data/public/css/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  517. data/public/css/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  518. data/public/css/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  519. data/public/css/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  520. data/public/css/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  521. data/public/css/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  522. data/public/css/smoothness/images/ui-icons_222222_256x240.png +0 -0
  523. data/public/css/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  524. data/public/css/smoothness/images/ui-icons_454545_256x240.png +0 -0
  525. data/public/css/smoothness/images/ui-icons_888888_256x240.png +0 -0
  526. data/public/css/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  527. data/public/css/smoothness/jquery-ui.css +565 -0
  528. data/public/css/smoothness/jquery.ui.accordion.css +19 -0
  529. data/public/css/smoothness/jquery.ui.all.css +11 -0
  530. data/public/css/smoothness/jquery.ui.autocomplete.css +53 -0
  531. data/public/css/smoothness/jquery.ui.base.css +11 -0
  532. data/public/css/smoothness/jquery.ui.button.css +38 -0
  533. data/public/css/smoothness/jquery.ui.core.css +38 -0
  534. data/public/css/smoothness/jquery.ui.datepicker.css +68 -0
  535. data/public/css/smoothness/jquery.ui.dialog.css +21 -0
  536. data/public/css/smoothness/jquery.ui.progressbar.css +11 -0
  537. data/public/css/smoothness/jquery.ui.resizable.css +20 -0
  538. data/public/css/smoothness/jquery.ui.selectable.css +10 -0
  539. data/public/css/smoothness/jquery.ui.slider.css +24 -0
  540. data/public/css/smoothness/jquery.ui.tabs.css +18 -0
  541. data/public/css/smoothness/jquery.ui.theme.css +249 -0
  542. data/public/css/south-street/images/ui-bg_glass_55_fcf0ba_1x400.png +0 -0
  543. data/public/css/south-street/images/ui-bg_gloss-wave_100_ece8da_500x100.png +0 -0
  544. data/public/css/south-street/images/ui-bg_highlight-hard_100_f5f3e5_1x100.png +0 -0
  545. data/public/css/south-street/images/ui-bg_highlight-hard_100_fafaf4_1x100.png +0 -0
  546. data/public/css/south-street/images/ui-bg_highlight-hard_15_459e00_1x100.png +0 -0
  547. data/public/css/south-street/images/ui-bg_highlight-hard_95_cccccc_1x100.png +0 -0
  548. data/public/css/south-street/images/ui-bg_highlight-soft_25_67b021_1x100.png +0 -0
  549. data/public/css/south-street/images/ui-bg_highlight-soft_95_ffedad_1x100.png +0 -0
  550. data/public/css/south-street/images/ui-bg_inset-soft_15_2b2922_1x100.png +0 -0
  551. data/public/css/south-street/images/ui-icons_808080_256x240.png +0 -0
  552. data/public/css/south-street/images/ui-icons_847e71_256x240.png +0 -0
  553. data/public/css/south-street/images/ui-icons_8dc262_256x240.png +0 -0
  554. data/public/css/south-street/images/ui-icons_cd0a0a_256x240.png +0 -0
  555. data/public/css/south-street/images/ui-icons_eeeeee_256x240.png +0 -0
  556. data/public/css/south-street/images/ui-icons_ffffff_256x240.png +0 -0
  557. data/public/css/south-street/jquery-ui.css +565 -0
  558. data/public/css/south-street/jquery.ui.accordion.css +19 -0
  559. data/public/css/south-street/jquery.ui.all.css +11 -0
  560. data/public/css/south-street/jquery.ui.autocomplete.css +53 -0
  561. data/public/css/south-street/jquery.ui.base.css +11 -0
  562. data/public/css/south-street/jquery.ui.button.css +38 -0
  563. data/public/css/south-street/jquery.ui.core.css +38 -0
  564. data/public/css/south-street/jquery.ui.datepicker.css +68 -0
  565. data/public/css/south-street/jquery.ui.dialog.css +21 -0
  566. data/public/css/south-street/jquery.ui.progressbar.css +11 -0
  567. data/public/css/south-street/jquery.ui.resizable.css +20 -0
  568. data/public/css/south-street/jquery.ui.selectable.css +10 -0
  569. data/public/css/south-street/jquery.ui.slider.css +24 -0
  570. data/public/css/south-street/jquery.ui.tabs.css +18 -0
  571. data/public/css/south-street/jquery.ui.theme.css +249 -0
  572. data/public/css/start/images/ui-bg_flat_55_999999_40x100.png +0 -0
  573. data/public/css/start/images/ui-bg_flat_75_aaaaaa_40x100.png +0 -0
  574. data/public/css/start/images/ui-bg_glass_45_0078ae_1x400.png +0 -0
  575. data/public/css/start/images/ui-bg_glass_55_f8da4e_1x400.png +0 -0
  576. data/public/css/start/images/ui-bg_glass_75_79c9ec_1x400.png +0 -0
  577. data/public/css/start/images/ui-bg_gloss-wave_45_e14f1c_500x100.png +0 -0
  578. data/public/css/start/images/ui-bg_gloss-wave_50_6eac2c_500x100.png +0 -0
  579. data/public/css/start/images/ui-bg_gloss-wave_75_2191c0_500x100.png +0 -0
  580. data/public/css/start/images/ui-bg_inset-hard_100_fcfdfd_1x100.png +0 -0
  581. data/public/css/start/images/ui-icons_0078ae_256x240.png +0 -0
  582. data/public/css/start/images/ui-icons_056b93_256x240.png +0 -0
  583. data/public/css/start/images/ui-icons_d8e7f3_256x240.png +0 -0
  584. data/public/css/start/images/ui-icons_e0fdff_256x240.png +0 -0
  585. data/public/css/start/images/ui-icons_f5e175_256x240.png +0 -0
  586. data/public/css/start/images/ui-icons_f7a50d_256x240.png +0 -0
  587. data/public/css/start/images/ui-icons_fcd113_256x240.png +0 -0
  588. data/public/css/start/jquery-ui.css +565 -0
  589. data/public/css/start/jquery.ui.accordion.css +19 -0
  590. data/public/css/start/jquery.ui.all.css +11 -0
  591. data/public/css/start/jquery.ui.autocomplete.css +53 -0
  592. data/public/css/start/jquery.ui.base.css +11 -0
  593. data/public/css/start/jquery.ui.button.css +38 -0
  594. data/public/css/start/jquery.ui.core.css +38 -0
  595. data/public/css/start/jquery.ui.datepicker.css +68 -0
  596. data/public/css/start/jquery.ui.dialog.css +21 -0
  597. data/public/css/start/jquery.ui.progressbar.css +11 -0
  598. data/public/css/start/jquery.ui.resizable.css +20 -0
  599. data/public/css/start/jquery.ui.selectable.css +10 -0
  600. data/public/css/start/jquery.ui.slider.css +24 -0
  601. data/public/css/start/jquery.ui.tabs.css +18 -0
  602. data/public/css/start/jquery.ui.theme.css +249 -0
  603. data/public/css/style.css +190 -0
  604. data/public/css/sunny/images/ui-bg_diagonals-medium_20_d34d17_40x40.png +0 -0
  605. data/public/css/sunny/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
  606. data/public/css/sunny/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
  607. data/public/css/sunny/images/ui-bg_gloss-wave_45_817865_500x100.png +0 -0
  608. data/public/css/sunny/images/ui-bg_gloss-wave_60_fece2f_500x100.png +0 -0
  609. data/public/css/sunny/images/ui-bg_gloss-wave_70_ffdd57_500x100.png +0 -0
  610. data/public/css/sunny/images/ui-bg_gloss-wave_90_fff9e5_500x100.png +0 -0
  611. data/public/css/sunny/images/ui-bg_highlight-soft_100_feeebd_1x100.png +0 -0
  612. data/public/css/sunny/images/ui-bg_inset-soft_30_ffffff_1x100.png +0 -0
  613. data/public/css/sunny/images/ui-icons_3d3d3d_256x240.png +0 -0
  614. data/public/css/sunny/images/ui-icons_bd7b00_256x240.png +0 -0
  615. data/public/css/sunny/images/ui-icons_d19405_256x240.png +0 -0
  616. data/public/css/sunny/images/ui-icons_eb990f_256x240.png +0 -0
  617. data/public/css/sunny/images/ui-icons_ed9f26_256x240.png +0 -0
  618. data/public/css/sunny/images/ui-icons_fadc7a_256x240.png +0 -0
  619. data/public/css/sunny/images/ui-icons_ffe180_256x240.png +0 -0
  620. data/public/css/sunny/jquery-ui.css +565 -0
  621. data/public/css/sunny/jquery.ui.accordion.css +19 -0
  622. data/public/css/sunny/jquery.ui.all.css +11 -0
  623. data/public/css/sunny/jquery.ui.autocomplete.css +53 -0
  624. data/public/css/sunny/jquery.ui.base.css +11 -0
  625. data/public/css/sunny/jquery.ui.button.css +38 -0
  626. data/public/css/sunny/jquery.ui.core.css +38 -0
  627. data/public/css/sunny/jquery.ui.datepicker.css +68 -0
  628. data/public/css/sunny/jquery.ui.dialog.css +21 -0
  629. data/public/css/sunny/jquery.ui.progressbar.css +11 -0
  630. data/public/css/sunny/jquery.ui.resizable.css +20 -0
  631. data/public/css/sunny/jquery.ui.selectable.css +10 -0
  632. data/public/css/sunny/jquery.ui.slider.css +24 -0
  633. data/public/css/sunny/jquery.ui.tabs.css +18 -0
  634. data/public/css/sunny/jquery.ui.theme.css +249 -0
  635. data/public/css/swanky-purse/images/ui-bg_diamond_10_4f4221_10x8.png +0 -0
  636. data/public/css/swanky-purse/images/ui-bg_diamond_20_372806_10x8.png +0 -0
  637. data/public/css/swanky-purse/images/ui-bg_diamond_25_675423_10x8.png +0 -0
  638. data/public/css/swanky-purse/images/ui-bg_diamond_25_d5ac5d_10x8.png +0 -0
  639. data/public/css/swanky-purse/images/ui-bg_diamond_8_261803_10x8.png +0 -0
  640. data/public/css/swanky-purse/images/ui-bg_diamond_8_443113_10x8.png +0 -0
  641. data/public/css/swanky-purse/images/ui-bg_flat_75_ddd4b0_40x100.png +0 -0
  642. data/public/css/swanky-purse/images/ui-bg_highlight-hard_65_fee4bd_1x100.png +0 -0
  643. data/public/css/swanky-purse/images/ui-icons_070603_256x240.png +0 -0
  644. data/public/css/swanky-purse/images/ui-icons_e8e2b5_256x240.png +0 -0
  645. data/public/css/swanky-purse/images/ui-icons_e9cd86_256x240.png +0 -0
  646. data/public/css/swanky-purse/images/ui-icons_efec9f_256x240.png +0 -0
  647. data/public/css/swanky-purse/images/ui-icons_f2ec64_256x240.png +0 -0
  648. data/public/css/swanky-purse/images/ui-icons_f9f2bd_256x240.png +0 -0
  649. data/public/css/swanky-purse/images/ui-icons_ff7519_256x240.png +0 -0
  650. data/public/css/swanky-purse/jquery-ui.css +565 -0
  651. data/public/css/swanky-purse/jquery.ui.accordion.css +19 -0
  652. data/public/css/swanky-purse/jquery.ui.all.css +11 -0
  653. data/public/css/swanky-purse/jquery.ui.autocomplete.css +53 -0
  654. data/public/css/swanky-purse/jquery.ui.base.css +11 -0
  655. data/public/css/swanky-purse/jquery.ui.button.css +38 -0
  656. data/public/css/swanky-purse/jquery.ui.core.css +38 -0
  657. data/public/css/swanky-purse/jquery.ui.datepicker.css +68 -0
  658. data/public/css/swanky-purse/jquery.ui.dialog.css +21 -0
  659. data/public/css/swanky-purse/jquery.ui.progressbar.css +11 -0
  660. data/public/css/swanky-purse/jquery.ui.resizable.css +20 -0
  661. data/public/css/swanky-purse/jquery.ui.selectable.css +10 -0
  662. data/public/css/swanky-purse/jquery.ui.slider.css +24 -0
  663. data/public/css/swanky-purse/jquery.ui.tabs.css +18 -0
  664. data/public/css/swanky-purse/jquery.ui.theme.css +249 -0
  665. data/public/css/trontastic/images/ui-bg_diagonals-small_50_262626_40x40.png +0 -0
  666. data/public/css/trontastic/images/ui-bg_flat_0_303030_40x100.png +0 -0
  667. data/public/css/trontastic/images/ui-bg_flat_0_4c4c4c_40x100.png +0 -0
  668. data/public/css/trontastic/images/ui-bg_glass_40_0a0a0a_1x400.png +0 -0
  669. data/public/css/trontastic/images/ui-bg_glass_55_f1fbe5_1x400.png +0 -0
  670. data/public/css/trontastic/images/ui-bg_glass_60_000000_1x400.png +0 -0
  671. data/public/css/trontastic/images/ui-bg_gloss-wave_55_000000_500x100.png +0 -0
  672. data/public/css/trontastic/images/ui-bg_gloss-wave_85_9fda58_500x100.png +0 -0
  673. data/public/css/trontastic/images/ui-bg_gloss-wave_95_f6ecd5_500x100.png +0 -0
  674. data/public/css/trontastic/images/ui-icons_000000_256x240.png +0 -0
  675. data/public/css/trontastic/images/ui-icons_1f1f1f_256x240.png +0 -0
  676. data/public/css/trontastic/images/ui-icons_9fda58_256x240.png +0 -0
  677. data/public/css/trontastic/images/ui-icons_b8ec79_256x240.png +0 -0
  678. data/public/css/trontastic/images/ui-icons_cd0a0a_256x240.png +0 -0
  679. data/public/css/trontastic/images/ui-icons_ffffff_256x240.png +0 -0
  680. data/public/css/trontastic/jquery-ui.css +565 -0
  681. data/public/css/trontastic/jquery.ui.accordion.css +19 -0
  682. data/public/css/trontastic/jquery.ui.all.css +11 -0
  683. data/public/css/trontastic/jquery.ui.autocomplete.css +53 -0
  684. data/public/css/trontastic/jquery.ui.base.css +11 -0
  685. data/public/css/trontastic/jquery.ui.button.css +38 -0
  686. data/public/css/trontastic/jquery.ui.core.css +38 -0
  687. data/public/css/trontastic/jquery.ui.datepicker.css +68 -0
  688. data/public/css/trontastic/jquery.ui.dialog.css +21 -0
  689. data/public/css/trontastic/jquery.ui.progressbar.css +11 -0
  690. data/public/css/trontastic/jquery.ui.resizable.css +20 -0
  691. data/public/css/trontastic/jquery.ui.selectable.css +10 -0
  692. data/public/css/trontastic/jquery.ui.slider.css +24 -0
  693. data/public/css/trontastic/jquery.ui.tabs.css +18 -0
  694. data/public/css/trontastic/jquery.ui.theme.css +249 -0
  695. data/public/css/ui-darkness/images/ui-bg_flat_30_cccccc_40x100.png +0 -0
  696. data/public/css/ui-darkness/images/ui-bg_flat_50_5c5c5c_40x100.png +0 -0
  697. data/public/css/ui-darkness/images/ui-bg_glass_20_555555_1x400.png +0 -0
  698. data/public/css/ui-darkness/images/ui-bg_glass_40_0078a3_1x400.png +0 -0
  699. data/public/css/ui-darkness/images/ui-bg_glass_40_ffc73d_1x400.png +0 -0
  700. data/public/css/ui-darkness/images/ui-bg_gloss-wave_25_333333_500x100.png +0 -0
  701. data/public/css/ui-darkness/images/ui-bg_highlight-soft_80_eeeeee_1x100.png +0 -0
  702. data/public/css/ui-darkness/images/ui-bg_inset-soft_25_000000_1x100.png +0 -0
  703. data/public/css/ui-darkness/images/ui-bg_inset-soft_30_f58400_1x100.png +0 -0
  704. data/public/css/ui-darkness/images/ui-icons_222222_256x240.png +0 -0
  705. data/public/css/ui-darkness/images/ui-icons_4b8e0b_256x240.png +0 -0
  706. data/public/css/ui-darkness/images/ui-icons_a83300_256x240.png +0 -0
  707. data/public/css/ui-darkness/images/ui-icons_cccccc_256x240.png +0 -0
  708. data/public/css/ui-darkness/images/ui-icons_ffffff_256x240.png +0 -0
  709. data/public/css/ui-darkness/jquery-ui.css +565 -0
  710. data/public/css/ui-darkness/jquery.ui.accordion.css +19 -0
  711. data/public/css/ui-darkness/jquery.ui.all.css +11 -0
  712. data/public/css/ui-darkness/jquery.ui.autocomplete.css +53 -0
  713. data/public/css/ui-darkness/jquery.ui.base.css +11 -0
  714. data/public/css/ui-darkness/jquery.ui.button.css +38 -0
  715. data/public/css/ui-darkness/jquery.ui.core.css +38 -0
  716. data/public/css/ui-darkness/jquery.ui.datepicker.css +68 -0
  717. data/public/css/ui-darkness/jquery.ui.dialog.css +21 -0
  718. data/public/css/ui-darkness/jquery.ui.progressbar.css +11 -0
  719. data/public/css/ui-darkness/jquery.ui.resizable.css +20 -0
  720. data/public/css/ui-darkness/jquery.ui.selectable.css +10 -0
  721. data/public/css/ui-darkness/jquery.ui.slider.css +24 -0
  722. data/public/css/ui-darkness/jquery.ui.tabs.css +18 -0
  723. data/public/css/ui-darkness/jquery.ui.theme.css +249 -0
  724. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
  725. data/public/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
  726. data/public/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
  727. data/public/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
  728. data/public/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
  729. data/public/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  730. data/public/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
  731. data/public/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
  732. data/public/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
  733. data/public/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
  734. data/public/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
  735. data/public/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
  736. data/public/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
  737. data/public/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
  738. data/public/css/ui-lightness/jquery-ui.css +565 -0
  739. data/public/css/ui-lightness/jquery.ui.accordion.css +19 -0
  740. data/public/css/ui-lightness/jquery.ui.all.css +11 -0
  741. data/public/css/ui-lightness/jquery.ui.autocomplete.css +53 -0
  742. data/public/css/ui-lightness/jquery.ui.base.css +11 -0
  743. data/public/css/ui-lightness/jquery.ui.button.css +38 -0
  744. data/public/css/ui-lightness/jquery.ui.core.css +38 -0
  745. data/public/css/ui-lightness/jquery.ui.datepicker.css +68 -0
  746. data/public/css/ui-lightness/jquery.ui.dialog.css +21 -0
  747. data/public/css/ui-lightness/jquery.ui.progressbar.css +11 -0
  748. data/public/css/ui-lightness/jquery.ui.resizable.css +20 -0
  749. data/public/css/ui-lightness/jquery.ui.selectable.css +10 -0
  750. data/public/css/ui-lightness/jquery.ui.slider.css +24 -0
  751. data/public/css/ui-lightness/jquery.ui.tabs.css +18 -0
  752. data/public/css/ui-lightness/jquery.ui.theme.css +249 -0
  753. data/public/css/vader/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  754. data/public/css/vader/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  755. data/public/css/vader/images/ui-bg_gloss-wave_16_121212_500x100.png +0 -0
  756. data/public/css/vader/images/ui-bg_highlight-hard_15_888888_1x100.png +0 -0
  757. data/public/css/vader/images/ui-bg_highlight-hard_55_555555_1x100.png +0 -0
  758. data/public/css/vader/images/ui-bg_highlight-soft_35_adadad_1x100.png +0 -0
  759. data/public/css/vader/images/ui-bg_highlight-soft_60_dddddd_1x100.png +0 -0
  760. data/public/css/vader/images/ui-bg_inset-soft_15_121212_1x100.png +0 -0
  761. data/public/css/vader/images/ui-icons_666666_256x240.png +0 -0
  762. data/public/css/vader/images/ui-icons_aaaaaa_256x240.png +0 -0
  763. data/public/css/vader/images/ui-icons_bbbbbb_256x240.png +0 -0
  764. data/public/css/vader/images/ui-icons_c98000_256x240.png +0 -0
  765. data/public/css/vader/images/ui-icons_cccccc_256x240.png +0 -0
  766. data/public/css/vader/images/ui-icons_cd0a0a_256x240.png +0 -0
  767. data/public/css/vader/images/ui-icons_f29a00_256x240.png +0 -0
  768. data/public/css/vader/jquery-ui.css +565 -0
  769. data/public/css/vader/jquery.ui.accordion.css +19 -0
  770. data/public/css/vader/jquery.ui.all.css +11 -0
  771. data/public/css/vader/jquery.ui.autocomplete.css +53 -0
  772. data/public/css/vader/jquery.ui.base.css +11 -0
  773. data/public/css/vader/jquery.ui.button.css +38 -0
  774. data/public/css/vader/jquery.ui.core.css +38 -0
  775. data/public/css/vader/jquery.ui.datepicker.css +68 -0
  776. data/public/css/vader/jquery.ui.dialog.css +21 -0
  777. data/public/css/vader/jquery.ui.progressbar.css +11 -0
  778. data/public/css/vader/jquery.ui.resizable.css +20 -0
  779. data/public/css/vader/jquery.ui.selectable.css +10 -0
  780. data/public/css/vader/jquery.ui.slider.css +24 -0
  781. data/public/css/vader/jquery.ui.tabs.css +18 -0
  782. data/public/css/vader/jquery.ui.theme.css +249 -0
  783. data/public/images/ui-anim_basic_16x16.gif +0 -0
  784. data/public/js/autocomplete.js +183 -0
  785. data/public/js/dictionary.js +93 -0
  786. data/public/js/index.js +217 -0
  787. data/public/js/jquery-1.7.1.min.js +4 -0
  788. data/public/js/jquery-ui-1.8.18.custom.min.js +356 -0
  789. data/test/helper.rb +31 -0
  790. data/test/unit/test_activity.rb +287 -0
  791. data/test/unit/test_application.rb +126 -0
  792. data/test/unit/test_database.rb +21 -0
  793. data/test/unit/test_hourglass.rb +9 -0
  794. data/views/_activity.erb +17 -0
  795. data/views/_current.erb +19 -0
  796. data/views/_today.erb +5 -0
  797. data/views/_week.erb +15 -0
  798. data/views/form.erb +35 -0
  799. data/views/index.erb +39 -0
  800. data/views/layout.erb +21 -0
  801. data/views/popup.erb +48 -0
  802. metadata +1060 -0
@@ -0,0 +1,73 @@
1
+ require 'pathname'
2
+ require 'rbconfig'
3
+ require 'delegate'
4
+ require 'sinatra/base'
5
+ require 'json'
6
+ require 'sequel'
7
+ require 'sequel/extensions/migration'
8
+ require 'logger'
9
+
10
+ module Hourglass
11
+ def self.root
12
+ File.expand_path(File.join(File.dirname(__FILE__), '..'))
13
+ end
14
+
15
+ def self.root_path
16
+ @root_path ||= Pathname.new(root)
17
+ end
18
+
19
+ def self.environment
20
+ @environment ||= ENV['HOURGLASS_ENV'] || :production
21
+ end
22
+
23
+ def self.db_path
24
+ File.join(data_path, 'db', "#{environment}.db")
25
+ end
26
+
27
+ def self.data_path
28
+ if !defined? @data_path
29
+ dir =
30
+ if ENV['HOURGLASS_HOME']
31
+ ENV['HOURGLASS_HOME']
32
+ else
33
+ case Config::CONFIG['host_os']
34
+ when /mswin|windows/i
35
+ # Windows
36
+ File.join(ENV['APPDATA'], "hourglass")
37
+ else
38
+ if ENV['HOME']
39
+ File.join(ENV['HOME'], ".hourglass")
40
+ else
41
+ raise "Can't figure out where Hourglass lives! Try setting the HOURGLASS_HOME environment variable"
42
+ end
43
+ end
44
+ end
45
+ if !File.exist?(dir)
46
+ begin
47
+ Dir.mkdir(dir)
48
+ rescue SystemCallError
49
+ raise "Can't create Hourglass directory (#{dir})! Is the parent directory accessible?"
50
+ end
51
+ end
52
+ if !File.writable?(dir)
53
+ raise "Hourglass directory (#{dir}) is not writable!"
54
+ end
55
+ @data_path = File.expand_path(dir)
56
+ end
57
+ @data_path
58
+ end
59
+
60
+ path = root_path + 'lib' + 'hourglass'
61
+ autoload :Project, (path + 'project').to_s
62
+ autoload :Activity, (path + 'activity').to_s
63
+ autoload :Tag, (path + 'tag').to_s
64
+ autoload :Setting, (path + 'setting').to_s
65
+ end
66
+
67
+ path = Hourglass.root_path + 'lib' + 'hourglass'
68
+ require path + 'database'
69
+ require path + 'application'
70
+ require path + 'runner'
71
+
72
+ Sequel::Model.plugin :json_serializer, :naked => true
73
+ Sequel::Model.plugin :validation_helpers
@@ -0,0 +1,284 @@
1
+ module Hourglass
2
+ class Activity < Sequel::Model
3
+ many_to_one :project
4
+ many_to_many :tags
5
+
6
+ plugin :json_serializer, :naked => true, :include => [:tags, :project]
7
+ plugin :nested_attributes
8
+ nested_attributes :project
9
+ plugin :dirty
10
+
11
+ def_dataset_method(:full) { eager(:tags, :project) }
12
+
13
+ subset(:current, :ended_at => nil)
14
+ def_dataset_method(:current_e) { current.full.order(:started_at) }
15
+
16
+ subset(:today) { started_at >= Date.today }
17
+ def_dataset_method(:today_e) { today.full.order(:started_at) }
18
+
19
+ subset(:week) do
20
+ today = Date.today
21
+ sunday = today - today.wday
22
+ (started_at >= sunday) & (started_at < (sunday + 7))
23
+ end
24
+ def_dataset_method(:week_e) { week.full.order(:started_at) }
25
+
26
+ subset(:sub_minute, ~{:ended_at => nil},
27
+ (:strftime.sql_function("%s", :ended_at) - :strftime.sql_function("%s", :started_at)) < 60)
28
+
29
+ def_dataset_method(:uniq) do
30
+ # figure out if the projects table has already been joined
31
+ ds =
32
+ if (opts[:join] || []).collect(&:table).include?(:projects)
33
+ self
34
+ else
35
+ join(:projects, :id => :project_id)
36
+ end
37
+ ds = ds.naked.
38
+ select(:min.sql_function(:activities__id).as(:id)).
39
+ group(:activities__name, :projects__name)
40
+
41
+ ids = ds.collect { |row| row[:id] }
42
+ filter(:activities__id => ids)
43
+ end
44
+
45
+ def self.stop_current_activities
46
+ current.update(:ended_at => Time.now)
47
+ ids = sub_minute.select_map(:id)
48
+ if !ids.empty?
49
+ db[:activities_tags].filter(:activity_id => ids).delete
50
+ sub_minute.delete
51
+ end
52
+ end
53
+
54
+ def running=(value)
55
+ modified!
56
+ @running = value
57
+ end
58
+
59
+ def started_at_date
60
+ t = started_at
61
+ Date.new(t.year, t.month, t.day)
62
+ end
63
+
64
+ def started_at_mdy
65
+ started_at ? started_at.strftime("%m/%d/%Y") : ""
66
+ end
67
+
68
+ def started_at_mdy=(value)
69
+ modified!
70
+ @started_at_mdy = value
71
+ end
72
+
73
+ def started_at_hm
74
+ started_at ? started_at.strftime("%H:%M") : ""
75
+ end
76
+
77
+ def started_at_hm=(value)
78
+ modified!
79
+ @started_at_hm = value
80
+ end
81
+
82
+ def ended_at_mdy
83
+ ended_at ? ended_at.strftime("%m/%d/%Y") : ""
84
+ end
85
+
86
+ def ended_at_mdy=(value)
87
+ modified!
88
+ @ended_at_mdy = value
89
+ end
90
+
91
+ def ended_at_hm
92
+ ended_at ? ended_at.strftime("%H:%M") : ""
93
+ end
94
+
95
+ def ended_at_hm=(value)
96
+ modified!
97
+ @ended_at_hm = value
98
+ end
99
+
100
+ def duration
101
+ (ended_at ? ended_at - started_at : Time.now - started_at).floor
102
+ end
103
+
104
+ def duration_in_words
105
+ total_minutes = duration / 60
106
+ if total_minutes == 0
107
+ "0min"
108
+ else
109
+ minutes = total_minutes % 60
110
+ total_hours = total_minutes / 60
111
+ hours = total_hours % 24
112
+ days = total_hours / 24
113
+
114
+ strings = []
115
+ strings << "#{days}d" if days > 0
116
+ strings << "#{hours}h" if hours > 0
117
+ strings << "#{minutes}min" if minutes > 0
118
+ strings.join(" ")
119
+ end
120
+ end
121
+
122
+ def running?
123
+ if new?
124
+ @running
125
+ else
126
+ ended_at.nil?
127
+ end
128
+ end
129
+
130
+ def tag_names
131
+ if @tag_names
132
+ @tag_names
133
+ else
134
+ new? ? "" : tags_dataset.select_map(:name).join(", ")
135
+ end
136
+ end
137
+
138
+ def tag_names=(value)
139
+ modified!
140
+ @tag_names = value
141
+ end
142
+
143
+ def name_with_project
144
+ if project
145
+ "#{name}@#{project.name}"
146
+ else
147
+ name
148
+ end
149
+ end
150
+
151
+ def name_with_project=(value)
152
+ activity_name, project_name = value ? value.strip.split("@", 2) : [nil, nil]
153
+ self.name = activity_name
154
+
155
+ if !project_name.nil? && !project_name.empty?
156
+ project = Project.filter(:name => project_name).first
157
+ if project.nil?
158
+ self.project_attributes = {:name => project_name}
159
+ else
160
+ self.project = project
161
+ end
162
+ end
163
+ end
164
+
165
+ def changes
166
+ @changes || {}
167
+ end
168
+
169
+ private
170
+
171
+ def before_validation
172
+ super
173
+ if @started_at_mdy && @started_at_hm
174
+ md_1 = @started_at_mdy.match(%r{^(\d{1,2})/(\d{1,2})/(\d{4})$})
175
+ md_2 = @started_at_hm.match(%r{^(\d{1,2}):(\d{2})$})
176
+ if md_1 && md_2
177
+ self.started_at = Time.local(md_1[3].to_i, md_1[1].to_i, md_1[2].to_i, md_2[1].to_i, md_2[2].to_i)
178
+ end
179
+ end
180
+
181
+ if @ended_at_mdy && @ended_at_hm
182
+ md_1 = @ended_at_mdy.match(%r{^(\d{1,2})/(\d{1,2})/(\d{4})$})
183
+ md_2 = @ended_at_hm.match(%r{^(\d{1,2}):(\d{2})$})
184
+ if md_1 && md_2
185
+ self.ended_at = Time.local(md_1[3].to_i, md_1[1].to_i, md_1[2].to_i, md_2[1].to_i, md_2[2].to_i)
186
+ end
187
+ end
188
+ end
189
+
190
+ def validate
191
+ super
192
+ validates_presence([:name, :started_at])
193
+ if (new? && !@running)
194
+ validates_presence([:ended_at])
195
+ end
196
+ end
197
+
198
+ def before_save
199
+ @changes = {}
200
+
201
+ if project && project.new?
202
+ @changes['new_project'] = project.name
203
+ end
204
+
205
+ super
206
+
207
+ if @running
208
+ self.ended_at = nil
209
+ end
210
+
211
+ if Activity.filter(:name => name, :project_id => project_id).count == 0
212
+ @changes['new_activity'] = name_with_project
213
+ end
214
+
215
+ if !new?
216
+ name_changed = changed_columns.include?(:name)
217
+ project_changed =
218
+ changed_columns.include?(:project_id) ||
219
+ (project && project.id != project_id)
220
+
221
+ if name_changed || project_changed
222
+ # check to see if this was the last activity named this
223
+ previous_name = initial_value(:name)
224
+ previous_project_id = initial_value(:project_id)
225
+ ds = Activity.
226
+ filter(:name => previous_name).
227
+ filter(:project_id => previous_project_id).
228
+ filter(~{:id => id})
229
+
230
+ if ds.count == 0
231
+ @changes['delete_activity'] =
232
+ if previous_project_id
233
+ previous_name + "@" + Project[previous_project_id].name
234
+ else
235
+ previous_name
236
+ end
237
+ end
238
+ end
239
+ end
240
+ end
241
+
242
+ def after_save
243
+ super
244
+ new_tags = []
245
+ if !@tag_names.nil? && !@tag_names.empty?
246
+ remove_all_tags
247
+ tag_names.split(/,\s*/).each do |tag_name|
248
+ tag_name = tag_name.strip
249
+ tag = Tag.filter(:name => tag_name).first
250
+ if tag.nil?
251
+ tag = Tag.create(:name => tag_name)
252
+ new_tags << tag_name
253
+ end
254
+ add_tag(tag)
255
+ end
256
+ end
257
+ if !new_tags.empty?
258
+ @changes['new_tags'] = new_tags
259
+ end
260
+
261
+ @tag_names = @started_at_mdy = @started_at_hm = @ended_at_mdy =
262
+ @ended_at_hm = @running = nil
263
+ end
264
+
265
+ def before_destroy
266
+ super
267
+ remove_all_tags
268
+
269
+ @changes = {}
270
+ end
271
+
272
+ def after_destroy
273
+ super
274
+
275
+ # NOTE: this doesn't work if someone changes an activity, then
276
+ # deletes it without saving, but this isn't really that critical.
277
+ if Activity.filter(:name => name, :project_id => project_id).count == 0
278
+ @changes['delete_activity'] = name_with_project
279
+ end
280
+
281
+ # TODO: Project.prune
282
+ end
283
+ end
284
+ end
@@ -0,0 +1,134 @@
1
+ module Hourglass
2
+ class Application < Sinatra::Base
3
+ set :root, Hourglass.root
4
+ set :erb, :trim => '-'
5
+
6
+ if development?
7
+ use Rack::CommonLogger
8
+ end
9
+
10
+ helpers do
11
+ def activity_tags(activity)
12
+ result = "<ul>"
13
+ activity.tags.each do |tag|
14
+ result << %{<li class="tag-#{tag.id}">#{tag.name}</li>}
15
+ end
16
+ result + "</ul>"
17
+ end
18
+
19
+ def all_partials
20
+ {
21
+ 'today' => erb(:_today, {
22
+ :layout => false,
23
+ :locals => {:activities => Activity.today_e.all}
24
+ }),
25
+ 'week' => erb(:_week, {
26
+ :layout => false,
27
+ :locals => {:activities => Activity.week_e.all}
28
+ }),
29
+ 'current' => erb(:_current, {
30
+ :layout => false,
31
+ :locals => {:activity => Activity.current_e.first}
32
+ })
33
+ }
34
+ end
35
+
36
+ def validate_and_save_activity(activity, was_running = false)
37
+ if activity.valid?
38
+ if !was_running && activity.running?
39
+ Activity.stop_current_activities
40
+ end
41
+ activity.save
42
+ if request.xhr?
43
+ all_partials.merge('changes' => activity.changes).to_json
44
+ else
45
+ redirect '/'
46
+ end
47
+ else
48
+ if request.xhr?
49
+ {'errors' => activity.errors}.to_json
50
+ else
51
+ erb :popup
52
+ end
53
+ end
54
+ end
55
+ end
56
+
57
+ before do
58
+ @user_agent = request.user_agent
59
+ end
60
+
61
+ get '/' do
62
+ if request.xhr?
63
+ all_partials.to_json
64
+ else
65
+ @activities = {
66
+ 'today' => Activity.today_e.all,
67
+ 'week' => Activity.week_e.all,
68
+ 'current' => Activity.current_e.first
69
+ }
70
+ erb :index
71
+ end
72
+ end
73
+
74
+ get '/activities/new' do
75
+ @activity = Activity.new(:started_at => Time.now, :running => true)
76
+ erb :popup
77
+ end
78
+
79
+ post '/activities' do
80
+ @activity = Activity.new(params['activity'] || {})
81
+ @activity.started_at ||= Time.now
82
+ validate_and_save_activity(@activity)
83
+ end
84
+
85
+ get '/activities/:id/edit' do
86
+ @activity = Activity[params[:id]]
87
+ erb :popup
88
+ end
89
+
90
+ post '/activities/:id' do
91
+ @activity = Activity[params[:id]]
92
+ was_running = @activity.running?
93
+ @activity.set_fields(params[:activity], [
94
+ :name_with_project, :tag_names, :running,
95
+ :started_at_mdy, :started_at_hm,
96
+ :ended_at_mdy, :ended_at_hm
97
+ ])
98
+ validate_and_save_activity(@activity, was_running)
99
+ end
100
+
101
+ get '/activities/:id/delete' do
102
+ activity = Activity[params[:id]]
103
+ activity.destroy
104
+ all_partials.merge('changes' => activity.changes).to_json
105
+ end
106
+
107
+ get '/activities' do
108
+ ds = Activity.naked.distinct.
109
+ select(:activities__name.as(:activity_name), :projects__name.as(:project_name)).
110
+ left_join(:projects, :id => :project_id).
111
+ order(:activities__name, :projects__name)
112
+ ds.collect do |row|
113
+ if row[:project_name]
114
+ "#{row[:activity_name]}@#{row[:project_name]}"
115
+ else
116
+ row[:activity_name]
117
+ end
118
+ end.to_json
119
+ end
120
+
121
+ get '/activities/current/stop' do
122
+ Activity.stop_current_activities
123
+ all_partials.to_json
124
+ end
125
+
126
+ get '/tags' do
127
+ Tag.naked.distinct.order(:name).select_map(:name).to_json
128
+ end
129
+
130
+ get '/projects' do
131
+ Project.naked.distinct.order(:name).select_map(:name).to_json
132
+ end
133
+ end
134
+ end