aa-rails4 0.6.0

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 (487) hide show
  1. checksums.yaml +7 -0
  2. data/.document +5 -0
  3. data/.gitignore +43 -0
  4. data/.travis.yml +8 -0
  5. data/.yardopts +7 -0
  6. data/CHANGELOG.md +894 -0
  7. data/CONTRIBUTING.md +121 -0
  8. data/Gemfile +40 -0
  9. data/Guardfile +7 -0
  10. data/LICENSE +25 -0
  11. data/README.rdoc +118 -0
  12. data/Rakefile +26 -0
  13. data/activeadmin.gemspec +33 -0
  14. data/app/assets/images/active_admin/admin_notes_icon.png +0 -0
  15. data/app/assets/images/active_admin/datepicker/datepicker-header-bg.png +0 -0
  16. data/app/assets/images/active_admin/datepicker/datepicker-input-icon.png +0 -0
  17. data/app/assets/images/active_admin/datepicker/datepicker-next-link-icon.png +0 -0
  18. data/app/assets/images/active_admin/datepicker/datepicker-nipple.png +0 -0
  19. data/app/assets/images/active_admin/datepicker/datepicker-prev-link-icon.png +0 -0
  20. data/app/assets/images/active_admin/index_list_icons/block_icon.svg +10 -0
  21. data/app/assets/images/active_admin/index_list_icons/blog_icon.svg +4 -0
  22. data/app/assets/images/active_admin/index_list_icons/grid_icon.svg +13 -0
  23. data/app/assets/images/active_admin/index_list_icons/table_icon.svg +3 -0
  24. data/app/assets/images/active_admin/loading.gif +0 -0
  25. data/app/assets/images/active_admin/nested_menu_arrow.gif +0 -0
  26. data/app/assets/images/active_admin/nested_menu_arrow_dark.gif +0 -0
  27. data/app/assets/images/active_admin/orderable.png +0 -0
  28. data/app/assets/javascripts/active_admin/application.js +3 -0
  29. data/app/assets/javascripts/active_admin/base.js +5 -0
  30. data/app/assets/javascripts/active_admin/components/jquery.aa.checkbox-toggler.js.coffee +37 -0
  31. data/app/assets/javascripts/active_admin/components/jquery.aa.dropdown-menu.js.coffee +105 -0
  32. data/app/assets/javascripts/active_admin/components/jquery.aa.popover.js.coffee +97 -0
  33. data/app/assets/javascripts/active_admin/components/jquery.aa.table-checkbox-toggler.js.coffee +25 -0
  34. data/app/assets/javascripts/active_admin/lib/namespace.js.coffee +3 -0
  35. data/app/assets/javascripts/active_admin/pages/application.js.coffee +21 -0
  36. data/app/assets/javascripts/active_admin/pages/batch_actions.js.coffee +26 -0
  37. data/app/assets/stylesheets/active_admin/_base.css.scss +41 -0
  38. data/app/assets/stylesheets/active_admin/_forms.css.scss +281 -0
  39. data/app/assets/stylesheets/active_admin/_header.css.scss +152 -0
  40. data/app/assets/stylesheets/active_admin/_mixins.css.scss +1 -0
  41. data/app/assets/stylesheets/active_admin/_typography.css.scss +100 -0
  42. data/app/assets/stylesheets/active_admin/components/_batch_actions.css.scss +11 -0
  43. data/app/assets/stylesheets/active_admin/components/_blank_slates.scss +31 -0
  44. data/app/assets/stylesheets/active_admin/components/_breadcrumbs.scss +20 -0
  45. data/app/assets/stylesheets/active_admin/components/_buttons.scss +11 -0
  46. data/app/assets/stylesheets/active_admin/components/_columns.scss +3 -0
  47. data/app/assets/stylesheets/active_admin/components/_comments.css.scss +41 -0
  48. data/app/assets/stylesheets/active_admin/components/_date_picker.css.scss +123 -0
  49. data/app/assets/stylesheets/active_admin/components/_dropdown_menu.scss +151 -0
  50. data/app/assets/stylesheets/active_admin/components/_flash_messages.css.scss +39 -0
  51. data/app/assets/stylesheets/active_admin/components/_grid.scss +9 -0
  52. data/app/assets/stylesheets/active_admin/components/_index_list.scss +12 -0
  53. data/app/assets/stylesheets/active_admin/components/_links.scss +5 -0
  54. data/app/assets/stylesheets/active_admin/components/_pagination.scss +34 -0
  55. data/app/assets/stylesheets/active_admin/components/_panels.scss +6 -0
  56. data/app/assets/stylesheets/active_admin/components/_popovers.css.scss +123 -0
  57. data/app/assets/stylesheets/active_admin/components/_scopes.scss +10 -0
  58. data/app/assets/stylesheets/active_admin/components/_status_tags.scss +12 -0
  59. data/app/assets/stylesheets/active_admin/components/_table_tools.css.scss +95 -0
  60. data/app/assets/stylesheets/active_admin/components/_tables.css.scss +108 -0
  61. data/app/assets/stylesheets/active_admin/mixins/_all.css.scss +11 -0
  62. data/app/assets/stylesheets/active_admin/mixins/_buttons.css.scss +66 -0
  63. data/app/assets/stylesheets/active_admin/mixins/_gradients.css.scss +38 -0
  64. data/app/assets/stylesheets/active_admin/mixins/_icons.css.scss +21 -0
  65. data/app/assets/stylesheets/active_admin/mixins/_reset.css.scss +165 -0
  66. data/app/assets/stylesheets/active_admin/mixins/_rounded.css.scss +43 -0
  67. data/app/assets/stylesheets/active_admin/mixins/_sections.css.scss +36 -0
  68. data/app/assets/stylesheets/active_admin/mixins/_shadows.css.scss +22 -0
  69. data/app/assets/stylesheets/active_admin/mixins/_typography.scss +3 -0
  70. data/app/assets/stylesheets/active_admin/mixins/_utilities.scss +26 -0
  71. data/app/assets/stylesheets/active_admin/mixins/_variables.css.scss +24 -0
  72. data/app/assets/stylesheets/active_admin/pages/_logged_out.scss +44 -0
  73. data/app/assets/stylesheets/active_admin/print.css.scss +284 -0
  74. data/app/assets/stylesheets/active_admin/structure/_footer.scss +14 -0
  75. data/app/assets/stylesheets/active_admin/structure/_main_structure.scss +26 -0
  76. data/app/assets/stylesheets/active_admin/structure/_title_bar.scss +44 -0
  77. data/app/views/active_admin/dashboard/index.html.arb +1 -0
  78. data/app/views/active_admin/devise/mailer/reset_password_instructions.html.erb +8 -0
  79. data/app/views/active_admin/devise/mailer/unlock_instructions.html.erb +7 -0
  80. data/app/views/active_admin/devise/passwords/edit.html.erb +19 -0
  81. data/app/views/active_admin/devise/passwords/new.html.erb +14 -0
  82. data/app/views/active_admin/devise/sessions/new.html.erb +18 -0
  83. data/app/views/active_admin/devise/shared/_links.erb +27 -0
  84. data/app/views/active_admin/devise/unlocks/new.html.erb +14 -0
  85. data/app/views/active_admin/page/index.html.arb +1 -0
  86. data/app/views/active_admin/resource/edit.html.arb +1 -0
  87. data/app/views/active_admin/resource/index.csv.erb +17 -0
  88. data/app/views/active_admin/resource/index.html.arb +1 -0
  89. data/app/views/active_admin/resource/new.html.arb +1 -0
  90. data/app/views/active_admin/resource/show.html.arb +1 -0
  91. data/app/views/layouts/active_admin.html.arb +1 -0
  92. data/app/views/layouts/active_admin_logged_out.html.erb +37 -0
  93. data/config/locales/bg.yml +101 -0
  94. data/config/locales/ca.yml +98 -0
  95. data/config/locales/cs.yml +92 -0
  96. data/config/locales/da.yml +102 -0
  97. data/config/locales/de-CH.yml +117 -0
  98. data/config/locales/de.yml +119 -0
  99. data/config/locales/en-GB.yml +90 -0
  100. data/config/locales/en.yml +101 -0
  101. data/config/locales/es.yml +106 -0
  102. data/config/locales/es_MX.yml +104 -0
  103. data/config/locales/fr.yml +89 -0
  104. data/config/locales/he.yml +91 -0
  105. data/config/locales/hr.yml +93 -0
  106. data/config/locales/hu.yml +92 -0
  107. data/config/locales/it.yml +89 -0
  108. data/config/locales/ja.yml +87 -0
  109. data/config/locales/ko.yml +84 -0
  110. data/config/locales/lt.yml +90 -0
  111. data/config/locales/lv.yml +89 -0
  112. data/config/locales/nl.yml +90 -0
  113. data/config/locales/no-NB.yml +85 -0
  114. data/config/locales/pl.yml +93 -0
  115. data/config/locales/pt-BR.yml +89 -0
  116. data/config/locales/pt-PT.yml +89 -0
  117. data/config/locales/ro.yml +93 -0
  118. data/config/locales/ru.yml +103 -0
  119. data/config/locales/sv-SE.yml +89 -0
  120. data/config/locales/tr.yml +90 -0
  121. data/config/locales/uk.yml +100 -0
  122. data/config/locales/vi.yml +90 -0
  123. data/config/locales/zh-CN.yml +90 -0
  124. data/config/locales/zh-TW.yml +90 -0
  125. data/cucumber.yml +3 -0
  126. data/docs/0-installation.md +56 -0
  127. data/docs/1-general-configuration.md +129 -0
  128. data/docs/10-custom-pages.md +96 -0
  129. data/docs/11-decorators.md +66 -0
  130. data/docs/12-arbre-components.md +144 -0
  131. data/docs/13-authorization-adapter.md +206 -0
  132. data/docs/2-resource-customization.md +292 -0
  133. data/docs/3-index-pages.md +191 -0
  134. data/docs/3-index-pages/create-an-index.md +29 -0
  135. data/docs/3-index-pages/index-as-block.md +16 -0
  136. data/docs/3-index-pages/index-as-blog.md +61 -0
  137. data/docs/3-index-pages/index-as-grid.md +21 -0
  138. data/docs/3-index-pages/index-as-table.md +120 -0
  139. data/docs/4-csv-format.md +32 -0
  140. data/docs/5-forms.md +72 -0
  141. data/docs/6-show-pages.md +43 -0
  142. data/docs/7-sidebars.md +42 -0
  143. data/docs/8-custom-actions.md +139 -0
  144. data/docs/9-batch-actions.md +161 -0
  145. data/features/action_item.feature +73 -0
  146. data/features/authorization.feature +64 -0
  147. data/features/authorization_cancan.feature +52 -0
  148. data/features/belongs_to.feature +63 -0
  149. data/features/breadcrumb.feature +27 -0
  150. data/features/comments/commenting.feature +128 -0
  151. data/features/comments/viewing_index.feature +19 -0
  152. data/features/dashboard.feature +16 -0
  153. data/features/decorators.feature +41 -0
  154. data/features/development_reloading.feature +31 -0
  155. data/features/edit_page.feature +127 -0
  156. data/features/favicon.feature +20 -0
  157. data/features/first_boot.feature +16 -0
  158. data/features/global_navigation.feature +29 -0
  159. data/features/i18n.feature +38 -0
  160. data/features/index/batch_actions.feature +123 -0
  161. data/features/index/filters.feature +94 -0
  162. data/features/index/format_as_csv.feature +117 -0
  163. data/features/index/formats.feature +39 -0
  164. data/features/index/index_as_block.feature +15 -0
  165. data/features/index/index_as_blog.feature +69 -0
  166. data/features/index/index_as_grid.feature +45 -0
  167. data/features/index/index_as_table.feature +195 -0
  168. data/features/index/index_blank_slate.feature +61 -0
  169. data/features/index/index_parameters.feature +75 -0
  170. data/features/index/index_scope_to.feature +56 -0
  171. data/features/index/index_scopes.feature +251 -0
  172. data/features/index/page_title.feature +30 -0
  173. data/features/index/pagination.feature +59 -0
  174. data/features/index/switch_index_view.feature +73 -0
  175. data/features/menu.feature +53 -0
  176. data/features/new_page.feature +119 -0
  177. data/features/registering_assets.feature +35 -0
  178. data/features/registering_pages.feature +148 -0
  179. data/features/registering_resources.feature +33 -0
  180. data/features/root_to.feature +17 -0
  181. data/features/show/default_content.feature +43 -0
  182. data/features/show/page_title.feature +47 -0
  183. data/features/sidebar_sections.feature +198 -0
  184. data/features/site_title.feature +47 -0
  185. data/features/specifying_actions.feature +93 -0
  186. data/features/step_definitions/action_item_steps.rb +7 -0
  187. data/features/step_definitions/action_link_steps.rb +7 -0
  188. data/features/step_definitions/additional_web_steps.rb +82 -0
  189. data/features/step_definitions/asset_steps.rb +15 -0
  190. data/features/step_definitions/attribute_steps.rb +13 -0
  191. data/features/step_definitions/batch_action_steps.rb +55 -0
  192. data/features/step_definitions/breadcrumb_steps.rb +3 -0
  193. data/features/step_definitions/comment_steps.rb +12 -0
  194. data/features/step_definitions/configuration_steps.rb +93 -0
  195. data/features/step_definitions/dashboard_steps.rb +15 -0
  196. data/features/step_definitions/factory_steps.rb +33 -0
  197. data/features/step_definitions/filter_steps.rb +17 -0
  198. data/features/step_definitions/flash_steps.rb +11 -0
  199. data/features/step_definitions/format_steps.rb +46 -0
  200. data/features/step_definitions/i18n_steps.rb +3 -0
  201. data/features/step_definitions/index_scope_steps.rb +21 -0
  202. data/features/step_definitions/index_views_steps.rb +3 -0
  203. data/features/step_definitions/layout_steps.rb +3 -0
  204. data/features/step_definitions/member_link_steps.rb +7 -0
  205. data/features/step_definitions/menu_steps.rb +11 -0
  206. data/features/step_definitions/pagination_steps.rb +8 -0
  207. data/features/step_definitions/sidebar_steps.rb +8 -0
  208. data/features/step_definitions/site_title_steps.rb +15 -0
  209. data/features/step_definitions/tab_steps.rb +3 -0
  210. data/features/step_definitions/table_steps.rb +119 -0
  211. data/features/step_definitions/user_steps.rb +39 -0
  212. data/features/step_definitions/web_steps.rb +82 -0
  213. data/features/sti_resource.feature +73 -0
  214. data/features/support/env.rb +118 -0
  215. data/features/support/paths.rb +63 -0
  216. data/features/support/selectors.rb +45 -0
  217. data/features/users/logging_in.feature +34 -0
  218. data/features/users/logging_out.feature +13 -0
  219. data/features/users/resetting_password.feature +34 -0
  220. data/lib/active_admin.rb +120 -0
  221. data/lib/active_admin/abstract_view_factory.rb +95 -0
  222. data/lib/active_admin/application.rb +245 -0
  223. data/lib/active_admin/asset_registration.rb +29 -0
  224. data/lib/active_admin/authorization_adapter.rb +132 -0
  225. data/lib/active_admin/base_controller.rb +78 -0
  226. data/lib/active_admin/base_controller/authorization.rb +153 -0
  227. data/lib/active_admin/base_controller/menu.rb +34 -0
  228. data/lib/active_admin/batch_actions.rb +17 -0
  229. data/lib/active_admin/batch_actions/controller.rb +25 -0
  230. data/lib/active_admin/batch_actions/resource_extension.rb +127 -0
  231. data/lib/active_admin/batch_actions/views/batch_action_form.rb +35 -0
  232. data/lib/active_admin/batch_actions/views/batch_action_popover.rb +28 -0
  233. data/lib/active_admin/batch_actions/views/batch_action_selector.rb +66 -0
  234. data/lib/active_admin/batch_actions/views/selection_cells.rb +37 -0
  235. data/lib/active_admin/callbacks.rb +87 -0
  236. data/lib/active_admin/cancan_adapter.rb +40 -0
  237. data/lib/active_admin/comments.rb +83 -0
  238. data/lib/active_admin/comments/comment.rb +49 -0
  239. data/lib/active_admin/comments/namespace_helper.rb +14 -0
  240. data/lib/active_admin/comments/resource_helper.rb +17 -0
  241. data/lib/active_admin/comments/show_page_helper.rb +23 -0
  242. data/lib/active_admin/comments/views.rb +2 -0
  243. data/lib/active_admin/comments/views/active_admin_comments.rb +75 -0
  244. data/lib/active_admin/component.rb +5 -0
  245. data/lib/active_admin/controller_action.rb +12 -0
  246. data/lib/active_admin/csv_builder.rb +49 -0
  247. data/lib/active_admin/deprecation.rb +36 -0
  248. data/lib/active_admin/devise.rb +70 -0
  249. data/lib/active_admin/dsl.rb +166 -0
  250. data/lib/active_admin/engine.rb +7 -0
  251. data/lib/active_admin/event.rb +33 -0
  252. data/lib/active_admin/filters.rb +9 -0
  253. data/lib/active_admin/filters/dsl.rb +21 -0
  254. data/lib/active_admin/filters/forms.rb +89 -0
  255. data/lib/active_admin/filters/formtastic_addons.rb +50 -0
  256. data/lib/active_admin/filters/resource_extension.rb +129 -0
  257. data/lib/active_admin/form_builder.rb +189 -0
  258. data/lib/active_admin/helpers/collection.rb +23 -0
  259. data/lib/active_admin/helpers/optional_display.rb +38 -0
  260. data/lib/active_admin/helpers/scope_chain.rb +23 -0
  261. data/lib/active_admin/helpers/settings.rb +108 -0
  262. data/lib/active_admin/iconic.rb +51 -0
  263. data/lib/active_admin/iconic/icons.rb +142 -0
  264. data/lib/active_admin/inputs.rb +15 -0
  265. data/lib/active_admin/inputs/datepicker_input.rb +11 -0
  266. data/lib/active_admin/inputs/filter_base.rb +33 -0
  267. data/lib/active_admin/inputs/filter_base/search_method_select.rb +73 -0
  268. data/lib/active_admin/inputs/filter_boolean_input.rb +32 -0
  269. data/lib/active_admin/inputs/filter_check_boxes_input.rb +40 -0
  270. data/lib/active_admin/inputs/filter_date_range_input.rb +34 -0
  271. data/lib/active_admin/inputs/filter_numeric_input.rb +10 -0
  272. data/lib/active_admin/inputs/filter_select_input.rb +45 -0
  273. data/lib/active_admin/inputs/filter_string_input.rb +24 -0
  274. data/lib/active_admin/menu.rb +107 -0
  275. data/lib/active_admin/menu_collection.rb +96 -0
  276. data/lib/active_admin/menu_item.rb +97 -0
  277. data/lib/active_admin/namespace.rb +221 -0
  278. data/lib/active_admin/page.rb +88 -0
  279. data/lib/active_admin/page_controller.rb +29 -0
  280. data/lib/active_admin/page_dsl.rb +28 -0
  281. data/lib/active_admin/page_presenter.rb +32 -0
  282. data/lib/active_admin/resource.rb +160 -0
  283. data/lib/active_admin/resource/action_items.rb +93 -0
  284. data/lib/active_admin/resource/belongs_to.rb +36 -0
  285. data/lib/active_admin/resource/controllers.rb +18 -0
  286. data/lib/active_admin/resource/menu.rb +64 -0
  287. data/lib/active_admin/resource/naming.rb +78 -0
  288. data/lib/active_admin/resource/page_presenters.rb +82 -0
  289. data/lib/active_admin/resource/pagination.rb +19 -0
  290. data/lib/active_admin/resource/routes.rb +99 -0
  291. data/lib/active_admin/resource/scope_to.rb +74 -0
  292. data/lib/active_admin/resource/scopes.rb +50 -0
  293. data/lib/active_admin/resource/sidebars.rb +27 -0
  294. data/lib/active_admin/resource_collection.rb +42 -0
  295. data/lib/active_admin/resource_controller.rb +51 -0
  296. data/lib/active_admin/resource_controller/action_builder.rb +21 -0
  297. data/lib/active_admin/resource_controller/actions.rb +81 -0
  298. data/lib/active_admin/resource_controller/data_access.rb +303 -0
  299. data/lib/active_admin/resource_controller/decorators.rb +20 -0
  300. data/lib/active_admin/resource_controller/resource_class_methods.rb +24 -0
  301. data/lib/active_admin/resource_controller/scoping.rb +31 -0
  302. data/lib/active_admin/resource_controller/sidebars.rb +18 -0
  303. data/lib/active_admin/resource_dsl.rb +134 -0
  304. data/lib/active_admin/router.rb +106 -0
  305. data/lib/active_admin/scope.rb +57 -0
  306. data/lib/active_admin/sidebar_section.rb +37 -0
  307. data/lib/active_admin/version.rb +3 -0
  308. data/lib/active_admin/view_factory.rb +28 -0
  309. data/lib/active_admin/view_helpers.rb +21 -0
  310. data/lib/active_admin/view_helpers/active_admin_application_helper.rb +12 -0
  311. data/lib/active_admin/view_helpers/assigns_with_indifferent_access_helper.rb +7 -0
  312. data/lib/active_admin/view_helpers/auto_link_helper.rb +34 -0
  313. data/lib/active_admin/view_helpers/breadcrumb_helper.rb +26 -0
  314. data/lib/active_admin/view_helpers/display_helper.rb +47 -0
  315. data/lib/active_admin/view_helpers/download_format_links_helper.rb +50 -0
  316. data/lib/active_admin/view_helpers/fields_for.rb +50 -0
  317. data/lib/active_admin/view_helpers/flash_helper.rb +13 -0
  318. data/lib/active_admin/view_helpers/form_helper.rb +24 -0
  319. data/lib/active_admin/view_helpers/icon_helper.rb +12 -0
  320. data/lib/active_admin/view_helpers/method_or_proc_helper.rb +93 -0
  321. data/lib/active_admin/view_helpers/sidebar_helper.rb +15 -0
  322. data/lib/active_admin/view_helpers/title_helper.rb +11 -0
  323. data/lib/active_admin/view_helpers/view_factory_helper.rb +11 -0
  324. data/lib/active_admin/views.rb +8 -0
  325. data/lib/active_admin/views/action_items.rb +17 -0
  326. data/lib/active_admin/views/components/action_list_popover.rb +29 -0
  327. data/lib/active_admin/views/components/attributes_table.rb +70 -0
  328. data/lib/active_admin/views/components/blank_slate.rb +17 -0
  329. data/lib/active_admin/views/components/columns.rb +150 -0
  330. data/lib/active_admin/views/components/dropdown_menu.rb +73 -0
  331. data/lib/active_admin/views/components/index_list.rb +68 -0
  332. data/lib/active_admin/views/components/paginated_collection.rb +123 -0
  333. data/lib/active_admin/views/components/panel.rb +34 -0
  334. data/lib/active_admin/views/components/popover.rb +27 -0
  335. data/lib/active_admin/views/components/scopes.rb +65 -0
  336. data/lib/active_admin/views/components/sidebar_section.rb +28 -0
  337. data/lib/active_admin/views/components/site_title.rb +55 -0
  338. data/lib/active_admin/views/components/status_tag.rb +56 -0
  339. data/lib/active_admin/views/components/table_for.rb +191 -0
  340. data/lib/active_admin/views/dashboard_section_renderer.rb +19 -0
  341. data/lib/active_admin/views/footer.rb +20 -0
  342. data/lib/active_admin/views/header.rb +32 -0
  343. data/lib/active_admin/views/index_as_block.rb +36 -0
  344. data/lib/active_admin/views/index_as_blog.rb +150 -0
  345. data/lib/active_admin/views/index_as_grid.rb +76 -0
  346. data/lib/active_admin/views/index_as_table.rb +238 -0
  347. data/lib/active_admin/views/pages/base.rb +139 -0
  348. data/lib/active_admin/views/pages/dashboard.rb +62 -0
  349. data/lib/active_admin/views/pages/form.rb +51 -0
  350. data/lib/active_admin/views/pages/index.rb +158 -0
  351. data/lib/active_admin/views/pages/layout.rb +26 -0
  352. data/lib/active_admin/views/pages/page.rb +30 -0
  353. data/lib/active_admin/views/pages/show.rb +59 -0
  354. data/lib/active_admin/views/tabbed_navigation.rb +62 -0
  355. data/lib/active_admin/views/title_bar.rb +53 -0
  356. data/lib/activeadmin.rb +1 -0
  357. data/lib/generators/active_admin/assets/assets_generator.rb +16 -0
  358. data/lib/generators/active_admin/assets/templates/active_admin.css.scss +17 -0
  359. data/lib/generators/active_admin/assets/templates/active_admin.js.coffee +1 -0
  360. data/lib/generators/active_admin/devise/devise_generator.rb +78 -0
  361. data/lib/generators/active_admin/install/install_generator.rb +46 -0
  362. data/lib/generators/active_admin/install/templates/active_admin.rb.erb +214 -0
  363. data/lib/generators/active_admin/install/templates/admin_user.rb.erb +27 -0
  364. data/lib/generators/active_admin/install/templates/dashboard.rb +33 -0
  365. data/lib/generators/active_admin/install/templates/migrations/create_active_admin_comments.rb +19 -0
  366. data/lib/generators/active_admin/resource/resource_generator.rb +16 -0
  367. data/lib/generators/active_admin/resource/templates/admin.rb +3 -0
  368. data/lib/ransack_ext.rb +12 -0
  369. data/script/local +44 -0
  370. data/script/use_rails +53 -0
  371. data/spec/integration/default_namespace_spec.rb +61 -0
  372. data/spec/integration/javascript_spec.rb +20 -0
  373. data/spec/integration/memory_spec.rb +29 -0
  374. data/spec/integration/stylesheets_spec.rb +41 -0
  375. data/spec/javascripts/coffeescripts/jquery.aa.checkbox-toggler-spec.js.coffee +50 -0
  376. data/spec/javascripts/coffeescripts/jquery.aa.popover-spec.js.coffee +82 -0
  377. data/spec/javascripts/coffeescripts/jquery.aa.table-checkbox-toggler-spec.js.coffee +34 -0
  378. data/spec/javascripts/compiled/jquery.aa.checkbox-toggler-spec.js +60 -0
  379. data/spec/javascripts/compiled/jquery.aa.popover-spec.js +106 -0
  380. data/spec/javascripts/compiled/jquery.aa.table-checkbox-toggler-spec.js +37 -0
  381. data/spec/javascripts/fixtures/checkboxes.html +9 -0
  382. data/spec/javascripts/fixtures/table_checkboxes.html +17 -0
  383. data/spec/javascripts/helpers/SpecHelper.js +3 -0
  384. data/spec/javascripts/helpers/vendor/jasmine-fixture-0.0.5.js +108 -0
  385. data/spec/javascripts/helpers/vendor/jasmine-jquery.js +288 -0
  386. data/spec/javascripts/helpers/vendor/sinon-1.2.0.js +2915 -0
  387. data/spec/javascripts/support/jasmine.yml +74 -0
  388. data/spec/javascripts/support/jasmine_config.rb +23 -0
  389. data/spec/javascripts/support/jasmine_runner.rb +32 -0
  390. data/spec/javascripts/support/jquery-ui-1.8.16.custom.min.js +34 -0
  391. data/spec/javascripts/support/jquery.min.js +4 -0
  392. data/spec/spec_helper.rb +175 -0
  393. data/spec/spec_helper_without_rails.rb +11 -0
  394. data/spec/support/deferred_garbage_collection.rb +19 -0
  395. data/spec/support/detect_rails_version.rb +42 -0
  396. data/spec/support/integration_example_group.rb +31 -0
  397. data/spec/support/jslint.yml +80 -0
  398. data/spec/support/rails_template.rb +104 -0
  399. data/spec/support/rails_template_with_data.rb +59 -0
  400. data/spec/support/templates/admin/stores.rb +11 -0
  401. data/spec/support/templates/cucumber.rb +24 -0
  402. data/spec/support/templates/cucumber_with_reloading.rb +5 -0
  403. data/spec/support/templates/en.yml +8 -0
  404. data/spec/support/templates/post_decorator.rb +53 -0
  405. data/spec/unit/abstract_view_factory_spec.rb +79 -0
  406. data/spec/unit/action_builder_spec.rb +126 -0
  407. data/spec/unit/active_admin_spec.rb +11 -0
  408. data/spec/unit/application_spec.rb +141 -0
  409. data/spec/unit/asset_registration_spec.rb +56 -0
  410. data/spec/unit/authorization/authorization_adapter_spec.rb +61 -0
  411. data/spec/unit/authorization/controller_authorization_spec.rb +39 -0
  412. data/spec/unit/auto_link_spec.rb +39 -0
  413. data/spec/unit/batch_actions/resource_spec.rb +91 -0
  414. data/spec/unit/batch_actions/settings_spec.rb +61 -0
  415. data/spec/unit/belongs_to_spec.rb +42 -0
  416. data/spec/unit/cancan_adapter_spec.rb +43 -0
  417. data/spec/unit/comments_spec.rb +106 -0
  418. data/spec/unit/component_spec.rb +18 -0
  419. data/spec/unit/config_shared_examples.rb +59 -0
  420. data/spec/unit/controller_filters_spec.rb +27 -0
  421. data/spec/unit/csv_builder_spec.rb +103 -0
  422. data/spec/unit/devise_spec.rb +116 -0
  423. data/spec/unit/dsl_spec.rb +61 -0
  424. data/spec/unit/event_spec.rb +47 -0
  425. data/spec/unit/filters/filter_form_builder_spec.rb +338 -0
  426. data/spec/unit/filters/resource_spec.rb +87 -0
  427. data/spec/unit/form_builder_spec.rb +478 -0
  428. data/spec/unit/generators/install_spec.rb +23 -0
  429. data/spec/unit/helpers/collection_spec.rb +65 -0
  430. data/spec/unit/helpers/scope_chain_spec.rb +36 -0
  431. data/spec/unit/helpers/settings_spec.rb +30 -0
  432. data/spec/unit/menu_collection_spec.rb +62 -0
  433. data/spec/unit/menu_item_spec.rb +143 -0
  434. data/spec/unit/menu_spec.rb +71 -0
  435. data/spec/unit/namespace/authorization_spec.rb +27 -0
  436. data/spec/unit/namespace/register_page_spec.rb +74 -0
  437. data/spec/unit/namespace/register_resource_spec.rb +163 -0
  438. data/spec/unit/namespace_spec.rb +103 -0
  439. data/spec/unit/page_controller_spec.rb +5 -0
  440. data/spec/unit/page_spec.rb +72 -0
  441. data/spec/unit/pretty_format_spec.rb +35 -0
  442. data/spec/unit/resource/action_items_spec.rb +62 -0
  443. data/spec/unit/resource/menu_spec.rb +18 -0
  444. data/spec/unit/resource/naming_spec.rb +108 -0
  445. data/spec/unit/resource/page_presenters_spec.rb +44 -0
  446. data/spec/unit/resource/pagination_spec.rb +38 -0
  447. data/spec/unit/resource/routes_spec.rb +73 -0
  448. data/spec/unit/resource/scopes_spec.rb +43 -0
  449. data/spec/unit/resource/sidebars_spec.rb +43 -0
  450. data/spec/unit/resource_collection_spec.rb +79 -0
  451. data/spec/unit/resource_controller/data_access_spec.rb +73 -0
  452. data/spec/unit/resource_controller/sidebars_spec.rb +46 -0
  453. data/spec/unit/resource_controller_spec.rb +265 -0
  454. data/spec/unit/resource_registration_spec.rb +56 -0
  455. data/spec/unit/resource_spec.rb +243 -0
  456. data/spec/unit/routing_spec.rb +172 -0
  457. data/spec/unit/scope_spec.rb +108 -0
  458. data/spec/unit/settings_spec.rb +88 -0
  459. data/spec/unit/view_factory_spec.rb +22 -0
  460. data/spec/unit/view_helpers/breadcrumbs_spec.rb +152 -0
  461. data/spec/unit/view_helpers/display_name_spec.rb +41 -0
  462. data/spec/unit/view_helpers/download_format_links_helper_spec.rb +39 -0
  463. data/spec/unit/view_helpers/fields_for_spec.rb +50 -0
  464. data/spec/unit/view_helpers/form_helper_spec.rb +56 -0
  465. data/spec/unit/view_helpers/method_or_proc_helper_spec.rb +97 -0
  466. data/spec/unit/views/components/action_list_popover_spec.rb +30 -0
  467. data/spec/unit/views/components/attributes_table_spec.rb +131 -0
  468. data/spec/unit/views/components/batch_action_popover_spec.rb +33 -0
  469. data/spec/unit/views/components/blank_slate_spec.rb +17 -0
  470. data/spec/unit/views/components/columns_spec.rb +142 -0
  471. data/spec/unit/views/components/index_list_spec.rb +32 -0
  472. data/spec/unit/views/components/paginated_collection_spec.rb +247 -0
  473. data/spec/unit/views/components/panel_spec.rb +51 -0
  474. data/spec/unit/views/components/popover_spec.rb +33 -0
  475. data/spec/unit/views/components/sidebar_section_spec.rb +37 -0
  476. data/spec/unit/views/components/site_title_spec.rb +78 -0
  477. data/spec/unit/views/components/status_tag_spec.rb +95 -0
  478. data/spec/unit/views/components/table_for_spec.rb +182 -0
  479. data/spec/unit/views/pages/layout_spec.rb +63 -0
  480. data/spec/unit/views/pages/show_spec.rb +20 -0
  481. data/spec/unit/views/tabbed_navigation_spec.rb +149 -0
  482. data/tasks/docs.rake +39 -0
  483. data/tasks/js.rake +32 -0
  484. data/tasks/parallel_tests.rake +60 -0
  485. data/tasks/test.rake +79 -0
  486. data/tasks/yard.rake +6 -0
  487. metadata +883 -0
@@ -0,0 +1,478 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveAdmin::FormBuilder do
4
+
5
+ # Setup an ActionView::Base object which can be used for
6
+ # generating the form for.
7
+ let(:helpers) do
8
+ view = action_view
9
+ def view.posts_path
10
+ "/posts"
11
+ end
12
+
13
+ def view.protect_against_forgery?
14
+ false
15
+ end
16
+
17
+ def view.url_for(*args)
18
+ if args.first == {:action => "index"}
19
+ posts_path
20
+ else
21
+ super
22
+ end
23
+ end
24
+
25
+ def view.a_helper_method
26
+ "A Helper Method"
27
+ end
28
+
29
+ view
30
+ end
31
+
32
+ def build_form(options = {}, form_object = Post.new, &block)
33
+ options = {:url => helpers.posts_path}.merge(options)
34
+
35
+ render_arbre_component({:form_object => form_object, :form_options => options, :form_block => block}, helpers)do
36
+ text_node active_admin_form_for(assigns[:form_object], assigns[:form_options], &assigns[:form_block])
37
+ end.to_s
38
+ end
39
+
40
+ context "in general with actions" do
41
+ let :body do
42
+ build_form do |f|
43
+ f.inputs do
44
+ f.input :title
45
+ f.input :body
46
+ end
47
+ f.actions do
48
+ f.action :submit, :label => "Submit Me"
49
+ f.action :submit, :label => "Another Button"
50
+ end
51
+ end
52
+ end
53
+
54
+ it "should generate a text input" do
55
+ body.should have_tag("input", :attributes => { :type => "text",
56
+ :name => "post[title]" })
57
+ end
58
+ it "should generate a textarea" do
59
+ body.should have_tag("textarea", :attributes => { :name => "post[body]" })
60
+ end
61
+ it "should only generate the form once" do
62
+ body.scan(/Title/).size.should == 1
63
+ end
64
+ it "should generate actions" do
65
+ body.should have_tag("input", :attributes => { :type => "submit",
66
+ :value => "Submit Me" })
67
+ body.should have_tag("input", :attributes => { :type => "submit",
68
+ :value => "Another Button" })
69
+ end
70
+ end
71
+
72
+ context "when polymorphic relationship" do
73
+ it "should raise error" do
74
+ expect {
75
+ comment = ActiveAdmin::Comment.new
76
+ build_form({:url => "admins/comments"}, comment) do |f|
77
+ f.inputs :resource
78
+ end
79
+ }.to raise_error(Formtastic::PolymorphicInputWithoutCollectionError)
80
+ end
81
+ end
82
+
83
+ describe "passing in options with actions" do
84
+ let :body do
85
+ build_form :html => { :multipart => true } do |f|
86
+ f.inputs :title
87
+ f.actions
88
+ end
89
+ end
90
+ it "should pass the options on to the form" do
91
+ body.should have_tag("form", :attributes => { :enctype => "multipart/form-data" })
92
+ end
93
+ end
94
+
95
+ describe "passing in options with actions" do
96
+ let :body do
97
+ build_form :html => { :multipart => true } do |f|
98
+ f.inputs :title
99
+ f.actions
100
+ end
101
+ end
102
+ it "should pass the options on to the form" do
103
+ body.should have_tag("form", :attributes => { :enctype => "multipart/form-data" })
104
+ end
105
+ end
106
+
107
+
108
+ context "with actions" do
109
+ it "should generate the form once" do
110
+ body = build_form do |f|
111
+ f.inputs do
112
+ f.input :title
113
+ end
114
+ f.actions
115
+ end
116
+ body.scan(/id="post_title"/).size.should == 1
117
+ end
118
+ it "should generate one button and a cancel link" do
119
+ body = build_form do |f|
120
+ f.actions
121
+ end
122
+ body.scan(/type="submit"/).size.should == 1
123
+ body.scan(/class="cancel"/).size.should == 1
124
+ end
125
+ it "should generate multiple actions" do
126
+ body = build_form do |f|
127
+ f.actions do
128
+ f.action :submit, :label => "Create & Continue"
129
+ f.action :submit, :label => "Create & Edit"
130
+ end
131
+ end
132
+ body.scan(/type="submit"/).size.should == 2
133
+ body.scan(/class="cancel"/).size.should == 0
134
+ end
135
+
136
+ end
137
+
138
+ context "with actions" do
139
+ it "should generate the form once" do
140
+ body = build_form do |f|
141
+ f.inputs do
142
+ f.input :title
143
+ end
144
+ f.actions
145
+ end
146
+ body.scan(/id="post_title"/).size.should == 1
147
+ end
148
+ it "should generate one button and a cancel link" do
149
+ body = build_form do |f|
150
+ f.actions
151
+ end
152
+ body.scan(/type="submit"/).size.should == 1
153
+ body.scan(/class="cancel"/).size.should == 1
154
+ end
155
+ it "should generate multiple actions" do
156
+ body = build_form do |f|
157
+ f.actions do
158
+ f.action :submit, :label => "Create & Continue"
159
+ f.action :submit, :label => "Create & Edit"
160
+ end
161
+ end
162
+ body.scan(/type="submit"/).size.should == 2
163
+ body.scan(/class="cancel"/).size.should == 0
164
+ end
165
+ end
166
+
167
+ context "without passing a block to inputs" do
168
+ let :body do
169
+ build_form do |f|
170
+ f.inputs :title, :body
171
+ end
172
+ end
173
+ it "should have a title input" do
174
+ body.should have_tag("input", :attributes => { :type => "text",
175
+ :name => "post[title]" })
176
+ end
177
+ it "should have a body textarea" do
178
+ body.should have_tag("textarea", :attributes => { :name => "post[body]" })
179
+ end
180
+ end
181
+
182
+ context "with semantic fields for" do
183
+ let :body do
184
+ build_form do |f|
185
+ f.inputs do
186
+ f.input :title
187
+ f.input :body
188
+ end
189
+ f.instance_eval do
190
+ @object.author = User.new
191
+ end
192
+ f.semantic_fields_for :author do |author|
193
+ author.inputs :first_name, :last_name
194
+ end
195
+ end
196
+ end
197
+ it "should generate a nested text input once" do
198
+ body.scan("post_author_attributes_first_name_input").size.should == 1
199
+ end
200
+ end
201
+
202
+ context "with collection inputs" do
203
+ before do
204
+ User.create :first_name => "John", :last_name => "Doe"
205
+ User.create :first_name => "Jane", :last_name => "Doe"
206
+ end
207
+
208
+ describe "as select" do
209
+ let :body do
210
+ build_form do |f|
211
+ f.input :author
212
+ end
213
+ end
214
+ it "should create 2 options" do
215
+ body.scan(/<option/).size.should == 3
216
+ end
217
+ end
218
+
219
+ describe "as radio buttons" do
220
+ let :body do
221
+ build_form do |f|
222
+ f.input :author, :as => :radio
223
+ end
224
+ end
225
+ it "should create 2 radio buttons" do
226
+ body.scan(/type="radio"/).size.should == 2
227
+ end
228
+ end
229
+
230
+ end
231
+
232
+ context "with inputs 'for'" do
233
+ let :body do
234
+ build_form do |f|
235
+ f.inputs do
236
+ f.input :title
237
+ f.input :body
238
+ end
239
+ f.instance_eval do
240
+ @object.author = User.new
241
+ end
242
+ f.inputs :name => 'Author', :for => :author do |author|
243
+ author.inputs :first_name, :last_name
244
+ end
245
+ end
246
+ end
247
+ it "should generate a nested text input once" do
248
+ body.scan("post_author_attributes_first_name_input").size.should == 1
249
+ end
250
+ it "should add an author first name field" do
251
+ body.should have_tag("input", :attributes => { :name => "post[author_attributes][first_name]"})
252
+ end
253
+ end
254
+
255
+ context "with wrapper html" do
256
+ it "should set a class" do
257
+ body = build_form do |f|
258
+ f.input :title, :wrapper_html => { :class => "important" }
259
+ end
260
+ body.should have_tag("li", :attributes => {:class => "important string input optional stringish"})
261
+ end
262
+ end
263
+
264
+ context "with has many inputs" do
265
+ describe "with simple block" do
266
+ let :body do
267
+ build_form({:url => '/categories'}, Category.new) do |f|
268
+ f.object.posts.build
269
+ f.has_many :posts do |p|
270
+ p.input :title
271
+ end
272
+ end
273
+ end
274
+
275
+ it "should translate the association name in header" do
276
+ begin
277
+ I18n.backend.store_translations(:en, :activerecord => { :models => { :post => { :one => "Blog Post", :other => "Blog Posts" } } })
278
+ body.should have_tag('h3', 'Blog Posts')
279
+ ensure
280
+ I18n.backend.reload!
281
+ end
282
+ end
283
+
284
+ it "should use model name when there is no translation for given model in header" do
285
+ body.should have_tag('h3', 'Post')
286
+ end
287
+
288
+ it "should translate the association name in has many new button" do
289
+ begin
290
+ I18n.backend.store_translations(:en, :activerecord => { :models => { :post => { :one => "Blog Post", :other => "Blog Posts" } } })
291
+ body.should have_tag('a', 'Add New Blog Post')
292
+ ensure
293
+ I18n.backend.reload!
294
+ end
295
+ end
296
+
297
+ it "should translate the attribute name" do
298
+ begin
299
+ I18n.backend.store_translations :en, :activerecord => { :attributes => { :post => { :title => 'A very nice title' } } }
300
+ body.should have_tag 'label', 'A very nice title'
301
+ ensure
302
+ I18n.backend.reload!
303
+ end
304
+ end
305
+
306
+ it "should use model name when there is no translation for given model in has many new button" do
307
+ body.should have_tag('a', 'Add New Post')
308
+ end
309
+
310
+ it "should render the nested form" do
311
+ body.should have_tag("input", :attributes => {:name => "category[posts_attributes][0][title]"})
312
+ end
313
+
314
+ it "should add a link to remove new nested records" do
315
+ Capybara.string(body).should have_css(".has_many > fieldset > ol > li.has_many_delete > a", :class => "button", :href => "#", :content => "Delete")
316
+ end
317
+
318
+ it "should include the nested record's class name in the js" do
319
+ body.should have_tag("a", :attributes => { :onclick => /NEW_POST_RECORD/ })
320
+ end
321
+
322
+ it "should add a link to add new nested records" do
323
+ Capybara.string(body).should have_css(".has_many > fieldset > ol > li > a", :class => "button", :href => "#", :content => "Add New Post")
324
+ end
325
+ end
326
+
327
+ describe "with complex block" do
328
+ let :body do
329
+ build_form({:url => '/categories'}, Category.new) do |f|
330
+ f.object.posts.build
331
+ f.has_many :posts do |p,i|
332
+ p.input :title, :label => "Title #{i}"
333
+ end
334
+ end
335
+ end
336
+
337
+ it "should accept a block with a second argument" do
338
+ body.should have_tag("label", "Title 1")
339
+ end
340
+
341
+ it "should add a custom header" do
342
+ body.should have_tag('h3', 'Post')
343
+ end
344
+
345
+ end
346
+
347
+ describe "without heading and new record link" do
348
+ let :body do
349
+ build_form({:url => '/categories'}, Category.new) do |f|
350
+ f.object.posts.build
351
+ f.has_many :posts, :heading => false, :new_record => false do |p|
352
+ p.input :title
353
+ end
354
+ end
355
+ end
356
+
357
+ it "should not add a header" do
358
+ body.should_not have_tag('h3', 'Post')
359
+ end
360
+
361
+ it "should not add link to new nested records" do
362
+ body.should_not have_tag('a', 'Add New Post')
363
+ end
364
+
365
+ end
366
+
367
+ describe "with custom heading" do
368
+ let :body do
369
+ build_form({:url => '/categories'}, Category.new) do |f|
370
+ f.object.posts.build
371
+ f.has_many :posts, :heading => "Test heading" do |p|
372
+ p.input :title
373
+ end
374
+ end
375
+ end
376
+
377
+ it "should add a custom header" do
378
+ body.should have_tag('h3', 'Test heading')
379
+ end
380
+
381
+ end
382
+
383
+ describe "with allow destroy" do
384
+ context "with an existing post" do
385
+ let :body do
386
+ build_form({:url => '/categories'}, Category.new) do |f|
387
+ f.object.posts.build.stub!(:new_record? => false)
388
+ f.has_many :posts, :allow_destroy => true do |p|
389
+ p.input :title
390
+ end
391
+ end
392
+ end
393
+
394
+ it "should include a boolean field for _destroy" do
395
+ body.should have_tag("input", :attributes => {:name => "category[posts_attributes][0][_destroy]"})
396
+ end
397
+
398
+ it "should have a check box with 'Remove' as its label" do
399
+ body.should have_tag("label", :attributes => {:for => "category_posts_attributes_0__destroy"}, :content => "Remove")
400
+ end
401
+
402
+ it "should wrap the destroy field in an li with class 'has_many_remove'" do
403
+ Capybara.string(body).should have_css(".has_many > fieldset > ol > li.has_many_remove > input")
404
+ end
405
+ end
406
+
407
+ context "with a new post" do
408
+ let :body do
409
+ build_form({:url => '/categories'}, Category.new) do |f|
410
+ f.object.posts.build
411
+ f.has_many :posts, :allow_destroy => true do |p|
412
+ p.input :title
413
+ end
414
+ end
415
+ end
416
+
417
+ it "should not have a boolean field for _destroy" do
418
+ body.should_not have_tag("input", :attributes => {:name => "category[posts_attributes][0][_destroy]"})
419
+ end
420
+
421
+ it "should not have a check box with 'Remove' as its label" do
422
+ body.should_not have_tag("label", :attributes => {:for => "category_posts_attributes_0__destroy"}, :content => "Remove")
423
+ end
424
+ end
425
+ end
426
+
427
+ pending "should render the block if it returns nil" do
428
+ body = build_form({:url => '/categories'}, Category.new) do |f|
429
+ f.object.posts.build
430
+ f.has_many :posts do |p|
431
+ p.input :title
432
+ nil
433
+ end
434
+ end
435
+
436
+ body.should have_tag("input", :attributes => {:name => "category[posts_attributes][0][title]"})
437
+ end
438
+ end
439
+
440
+ { # Testing that the same input can be used multiple times
441
+ "f.input :title, :as => :string" => /id="post_title"/,
442
+ "f.input :title, :as => :text" => /id="post_title"/,
443
+ "f.input :created_at, :as => :time_select" => /id="post_created_at_2i"/,
444
+ "f.input :created_at, :as => :datetime_select" => /id="post_created_at_2i"/,
445
+ "f.input :created_at, :as => :date_select" => /id="post_created_at_2i"/,
446
+ # Testing that return values don't screw up the form
447
+ "f.input :title; nil" => /id="post_title"/,
448
+ "f.input :title; []" => /id="post_title"/,
449
+ "[:title].each{ |r| f.input r }" => /id="post_title"/,
450
+ "[:title].map { |r| f.input r }" => /id="post_title"/,
451
+ }.each do |source, regex|
452
+ it "should properly buffer `#{source}`" do
453
+ body = build_form do |f|
454
+ f.inputs do
455
+ eval source
456
+ eval source
457
+ end
458
+ end
459
+ body.scan(regex).size.should == 2
460
+ end
461
+ end
462
+
463
+ describe "datepicker input" do
464
+ let :body do
465
+ build_form do |f|
466
+ f.inputs do
467
+ f.input :created_at, :as => :datepicker
468
+ end
469
+ end
470
+ end
471
+ it "should generate a text input with the class of datepicker" do
472
+ body.should have_tag("input", :attributes => { :type => "text",
473
+ :class => "datepicker",
474
+ :name => "post[created_at]" })
475
+ end
476
+ end
477
+
478
+ end