decidim-enhanced_textwork 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (441) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +64 -0
  3. data/Rakefile +3 -0
  4. data/app/cells/decidim/enhanced_textwork/amendment/show.erb +14 -0
  5. data/app/cells/decidim/enhanced_textwork/amendment_cell.rb +39 -0
  6. data/app/cells/decidim/enhanced_textwork/collaborative_draft_cell.rb +49 -0
  7. data/app/cells/decidim/enhanced_textwork/collaborative_draft_link_to_paragraph/show.erb +13 -0
  8. data/app/cells/decidim/enhanced_textwork/collaborative_draft_link_to_paragraph_cell.rb +57 -0
  9. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m/footer.erb +6 -0
  10. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m/tags.erb +1 -0
  11. data/app/cells/decidim/enhanced_textwork/collaborative_draft_m_cell.rb +44 -0
  12. data/app/cells/decidim/enhanced_textwork/collaborative_drafts/reported_content/show.erb +3 -0
  13. data/app/cells/decidim/enhanced_textwork/collaborative_drafts/reported_content_cell.rb +15 -0
  14. data/app/cells/decidim/enhanced_textwork/comments/show.erb +33 -0
  15. data/app/cells/decidim/enhanced_textwork/comments_cell.rb +8 -0
  16. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs/elements.erb +5 -0
  17. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs/heading.erb +1 -0
  18. data/app/cells/decidim/enhanced_textwork/content_blocks/highlighted_paragraphs_cell.rb +19 -0
  19. data/app/cells/decidim/enhanced_textwork/cost_report/show.erb +35 -0
  20. data/app/cells/decidim/enhanced_textwork/cost_report_cell.rb +42 -0
  21. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs/show.erb +3 -0
  22. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_cell.rb +25 -0
  23. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_for_component/show.erb +19 -0
  24. data/app/cells/decidim/enhanced_textwork/highlighted_paragraphs_for_component_cell.rb +41 -0
  25. data/app/cells/decidim/enhanced_textwork/irreversible_action_modal/show.erb +27 -0
  26. data/app/cells/decidim/enhanced_textwork/irreversible_action_modal_cell.rb +80 -0
  27. data/app/cells/decidim/enhanced_textwork/paragraph_activity_cell.rb +35 -0
  28. data/app/cells/decidim/enhanced_textwork/paragraph_cell.rb +53 -0
  29. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_collaborative_draft_cell.rb +26 -0
  30. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_rejected_emendation/show.erb +9 -0
  31. data/app/cells/decidim/enhanced_textwork/paragraph_link_to_rejected_emendation_cell.rb +34 -0
  32. data/app/cells/decidim/enhanced_textwork/paragraph_linked_resources/show.erb +9 -0
  33. data/app/cells/decidim/enhanced_textwork/paragraph_linked_resources_cell.rb +14 -0
  34. data/app/cells/decidim/enhanced_textwork/paragraph_m/footer.erb +26 -0
  35. data/app/cells/decidim/enhanced_textwork/paragraph_m/tags.erb +1 -0
  36. data/app/cells/decidim/enhanced_textwork/paragraph_m_cell.rb +152 -0
  37. data/app/cells/decidim/enhanced_textwork/paragraph_tags/show.erb +33 -0
  38. data/app/cells/decidim/enhanced_textwork/paragraph_tags_cell.rb +35 -0
  39. data/app/cells/decidim/enhanced_textwork/paragraphs_picker/paragraphs.erb +12 -0
  40. data/app/cells/decidim/enhanced_textwork/paragraphs_picker/show.erb +14 -0
  41. data/app/cells/decidim/enhanced_textwork/paragraphs_picker_cell.rb +72 -0
  42. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph/buttons.erb +33 -0
  43. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph/show.erb +38 -0
  44. data/app/cells/decidim/enhanced_textwork/participatory_text_paragraph_cell.rb +104 -0
  45. data/app/cells/decidim/enhanced_textwork/reported_content/show.erb +4 -0
  46. data/app/cells/decidim/enhanced_textwork/reported_content_cell.rb +13 -0
  47. data/app/commands/decidim/enhanced_textwork/accept_access_to_collaborative_draft.rb +70 -0
  48. data/app/commands/decidim/enhanced_textwork/admin/answer_paragraph.rb +74 -0
  49. data/app/commands/decidim/enhanced_textwork/admin/assign_paragraphs_to_valuator.rb +61 -0
  50. data/app/commands/decidim/enhanced_textwork/admin/create_paragraph.rb +97 -0
  51. data/app/commands/decidim/enhanced_textwork/admin/create_paragraph_note.rb +67 -0
  52. data/app/commands/decidim/enhanced_textwork/admin/destroy_paragraph.rb +32 -0
  53. data/app/commands/decidim/enhanced_textwork/admin/discard_participatory_text.rb +40 -0
  54. data/app/commands/decidim/enhanced_textwork/admin/import_from_editor_participatory_text.rb +53 -0
  55. data/app/commands/decidim/enhanced_textwork/admin/import_paragraphs.rb +101 -0
  56. data/app/commands/decidim/enhanced_textwork/admin/import_participatory_text.rb +55 -0
  57. data/app/commands/decidim/enhanced_textwork/admin/merge_paragraphs.rb +69 -0
  58. data/app/commands/decidim/enhanced_textwork/admin/notify_paragraph_answer.rb +85 -0
  59. data/app/commands/decidim/enhanced_textwork/admin/publish_answers.rb +67 -0
  60. data/app/commands/decidim/enhanced_textwork/admin/publish_participatory_text.rb +81 -0
  61. data/app/commands/decidim/enhanced_textwork/admin/split_paragraphs.rb +67 -0
  62. data/app/commands/decidim/enhanced_textwork/admin/unassign_paragraphs_from_valuator.rb +62 -0
  63. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph.rb +86 -0
  64. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph_category.rb +68 -0
  65. data/app/commands/decidim/enhanced_textwork/admin/update_paragraph_scope.rb +75 -0
  66. data/app/commands/decidim/enhanced_textwork/admin/update_participatory_text.rb +68 -0
  67. data/app/commands/decidim/enhanced_textwork/create_collaborative_draft.rb +81 -0
  68. data/app/commands/decidim/enhanced_textwork/create_paragraph.rb +106 -0
  69. data/app/commands/decidim/enhanced_textwork/destroy_paragraph.rb +33 -0
  70. data/app/commands/decidim/enhanced_textwork/gallery_methods.rb +18 -0
  71. data/app/commands/decidim/enhanced_textwork/hashtags_methods.rb +36 -0
  72. data/app/commands/decidim/enhanced_textwork/publish_collaborative_draft.rb +93 -0
  73. data/app/commands/decidim/enhanced_textwork/publish_paragraph.rb +105 -0
  74. data/app/commands/decidim/enhanced_textwork/reject_access_to_collaborative_draft.rb +62 -0
  75. data/app/commands/decidim/enhanced_textwork/request_access_to_collaborative_draft.rb +49 -0
  76. data/app/commands/decidim/enhanced_textwork/unvote_paragraph.rb +65 -0
  77. data/app/commands/decidim/enhanced_textwork/update_collaborative_draft.rb +63 -0
  78. data/app/commands/decidim/enhanced_textwork/update_paragraph.rb +135 -0
  79. data/app/commands/decidim/enhanced_textwork/vote_paragraph.rb +77 -0
  80. data/app/commands/decidim/enhanced_textwork/withdraw_collaborative_draft.rb +65 -0
  81. data/app/commands/decidim/enhanced_textwork/withdraw_paragraph.rb +50 -0
  82. data/app/controllers/concerns/decidim/enhanced_textwork/admin/filterable.rb +82 -0
  83. data/app/controllers/concerns/decidim/enhanced_textwork/admin/picker.rb +21 -0
  84. data/app/controllers/concerns/decidim/enhanced_textwork/collaborative_orderable.rb +42 -0
  85. data/app/controllers/concerns/decidim/enhanced_textwork/orderable.rb +78 -0
  86. data/app/controllers/decidim/enhanced_textwork/admin/application_controller.rb +16 -0
  87. data/app/controllers/decidim/enhanced_textwork/admin/paragraph_answers_controller.rb +50 -0
  88. data/app/controllers/decidim/enhanced_textwork/admin/paragraph_notes_controller.rb +39 -0
  89. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_controller.rb +237 -0
  90. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_imports_controller.rb +33 -0
  91. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_merges_controller.rb +30 -0
  92. data/app/controllers/decidim/enhanced_textwork/admin/paragraphs_splits_controller.rb +30 -0
  93. data/app/controllers/decidim/enhanced_textwork/admin/participatory_texts_controller.rb +128 -0
  94. data/app/controllers/decidim/enhanced_textwork/admin/valuation_assignments_controller.rb +58 -0
  95. data/app/controllers/decidim/enhanced_textwork/application_controller.rb +31 -0
  96. data/app/controllers/decidim/enhanced_textwork/collaborative_draft_collaborator_requests_controller.rb +53 -0
  97. data/app/controllers/decidim/enhanced_textwork/collaborative_drafts_controller.rb +161 -0
  98. data/app/controllers/decidim/enhanced_textwork/paragraph_votes_controller.rb +65 -0
  99. data/app/controllers/decidim/enhanced_textwork/paragraphs_controller.rb +316 -0
  100. data/app/controllers/decidim/enhanced_textwork/versions_controller.rb +21 -0
  101. data/app/controllers/decidim/enhanced_textwork/widgets_controller.rb +19 -0
  102. data/app/events/decidim/enhanced_textwork/accepted_paragraph_event.rb +17 -0
  103. data/app/events/decidim/enhanced_textwork/admin/paragraph_note_created_event.rb +27 -0
  104. data/app/events/decidim/enhanced_textwork/admin/update_paragraph_category_event.rb +11 -0
  105. data/app/events/decidim/enhanced_textwork/admin/update_paragraph_scope_event.rb +11 -0
  106. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_accepted_event.rb +8 -0
  107. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_rejected_event.rb +8 -0
  108. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_request_event.rb +27 -0
  109. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requested_event.rb +8 -0
  110. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requester_accepted_event.rb +8 -0
  111. data/app/events/decidim/enhanced_textwork/collaborative_draft_access_requester_rejected_event.rb +8 -0
  112. data/app/events/decidim/enhanced_textwork/collaborative_draft_withdrawn_event.rb +29 -0
  113. data/app/events/decidim/enhanced_textwork/creation_enabled_event.rb +8 -0
  114. data/app/events/decidim/enhanced_textwork/endorsing_enabled_event.rb +8 -0
  115. data/app/events/decidim/enhanced_textwork/evaluating_paragraph_event.rb +11 -0
  116. data/app/events/decidim/enhanced_textwork/paragraph_endorsed_event.rb +33 -0
  117. data/app/events/decidim/enhanced_textwork/paragraph_mentioned_event.rb +21 -0
  118. data/app/events/decidim/enhanced_textwork/publish_paragraph_event.rb +25 -0
  119. data/app/events/decidim/enhanced_textwork/rejected_paragraph_event.rb +17 -0
  120. data/app/events/decidim/enhanced_textwork/voting_enabled_event.rb +8 -0
  121. data/app/forms/decidim/enhanced_textwork/accept_access_to_collaborative_draft_form.rb +10 -0
  122. data/app/forms/decidim/enhanced_textwork/access_to_collaborative_draft_form.rb +33 -0
  123. data/app/forms/decidim/enhanced_textwork/admin/import_editor_participatory_text_form.rb +35 -0
  124. data/app/forms/decidim/enhanced_textwork/admin/import_participatory_text_form.rb +68 -0
  125. data/app/forms/decidim/enhanced_textwork/admin/paragraph_answer_form.rb +44 -0
  126. data/app/forms/decidim/enhanced_textwork/admin/paragraph_base_form.rb +137 -0
  127. data/app/forms/decidim/enhanced_textwork/admin/paragraph_form.rb +32 -0
  128. data/app/forms/decidim/enhanced_textwork/admin/paragraph_note_form.rb +16 -0
  129. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_fork_form.rb +63 -0
  130. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_import_form.rb +67 -0
  131. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_merge_form.rb +13 -0
  132. data/app/forms/decidim/enhanced_textwork/admin/paragraphs_split_form.rb +12 -0
  133. data/app/forms/decidim/enhanced_textwork/admin/participatory_text_paragraph_form.rb +20 -0
  134. data/app/forms/decidim/enhanced_textwork/admin/preview_participatory_text_form.rb +21 -0
  135. data/app/forms/decidim/enhanced_textwork/admin/valuation_assignment_form.rb +37 -0
  136. data/app/forms/decidim/enhanced_textwork/collaborative_draft_form.rb +20 -0
  137. data/app/forms/decidim/enhanced_textwork/paragraph_form.rb +126 -0
  138. data/app/forms/decidim/enhanced_textwork/paragraph_wizard_create_step_form.rb +41 -0
  139. data/app/forms/decidim/enhanced_textwork/reject_access_to_collaborative_draft_form.rb +9 -0
  140. data/app/forms/decidim/enhanced_textwork/request_access_to_collaborative_draft_form.rb +20 -0
  141. data/app/helpers/decidim/enhanced_textwork/admin/filterable_helper.rb +17 -0
  142. data/app/helpers/decidim/enhanced_textwork/admin/paragraph_bulk_actions_helper.rb +35 -0
  143. data/app/helpers/decidim/enhanced_textwork/admin/paragraph_rankings_helper.rb +63 -0
  144. data/app/helpers/decidim/enhanced_textwork/admin/paragraphs_helper.rb +144 -0
  145. data/app/helpers/decidim/enhanced_textwork/admin/paragraphs_picker_helper.rb +30 -0
  146. data/app/helpers/decidim/enhanced_textwork/application_helper.rb +191 -0
  147. data/app/helpers/decidim/enhanced_textwork/collaborative_draft_cells_helper.rb +48 -0
  148. data/app/helpers/decidim/enhanced_textwork/collaborative_draft_helper.rb +29 -0
  149. data/app/helpers/decidim/enhanced_textwork/control_version_helper.rb +12 -0
  150. data/app/helpers/decidim/enhanced_textwork/map_helper.rb +48 -0
  151. data/app/helpers/decidim/enhanced_textwork/paragraph_cells_helper.rb +75 -0
  152. data/app/helpers/decidim/enhanced_textwork/paragraph_votes_helper.rb +103 -0
  153. data/app/helpers/decidim/enhanced_textwork/paragraph_wizard_helper.rb +140 -0
  154. data/app/helpers/decidim/enhanced_textwork/paragraphs_helper.rb +63 -0
  155. data/app/helpers/decidim/enhanced_textwork/participatory_texts_helper.rb +49 -0
  156. data/app/jobs/decidim/enhanced_textwork/notify_paragraphs_mentioned_job.rb +27 -0
  157. data/app/jobs/decidim/enhanced_textwork/settings_change_job.rb +50 -0
  158. data/app/models/decidim/enhanced_textwork/application_record.rb +10 -0
  159. data/app/models/decidim/enhanced_textwork/collaborative_draft.rb +73 -0
  160. data/app/models/decidim/enhanced_textwork/collaborative_draft_collaborator_request.rb +13 -0
  161. data/app/models/decidim/enhanced_textwork/paragraph.rb +411 -0
  162. data/app/models/decidim/enhanced_textwork/paragraph_note.rb +20 -0
  163. data/app/models/decidim/enhanced_textwork/paragraph_vote.rb +50 -0
  164. data/app/models/decidim/enhanced_textwork/participatory_text.rb +16 -0
  165. data/app/models/decidim/enhanced_textwork/valuation_assignment.rb +24 -0
  166. data/app/packs/documents/decidim/enhanced_textwork/participatory_texts/participatory_text.md +52 -0
  167. data/app/packs/documents/decidim/enhanced_textwork/participatory_texts/participatory_text.odt +0 -0
  168. data/app/packs/entrypoints/decidim_enhanced_textwork.js +17 -0
  169. data/app/packs/entrypoints/decidim_enhanced_textwork_admin.js +3 -0
  170. data/app/packs/images/decidim/enhanced_textwork/decidim_paragraphs.svg +1 -0
  171. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_accepted_paragraphs.svg +1 -0
  172. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_paragraph_votes.svg +1 -0
  173. data/app/packs/images/decidim/gamification/badges/decidim_gamification_badges_paragraphs.svg +1 -0
  174. data/app/packs/src/decidim/enhanced_textwork/add_paragraph.js +49 -0
  175. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs.js +143 -0
  176. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs_form.js +29 -0
  177. data/app/packs/src/decidim/enhanced_textwork/admin/paragraphs_picker.js +35 -0
  178. data/app/packs/src/decidim/enhanced_textwork/toggle_element.js +21 -0
  179. data/app/packs/src/decidim/enhanced_textwork/utils.js +11 -0
  180. data/app/packs/stylesheets/decidim/enhanced_textwork/_paragraphs.scss +208 -0
  181. data/app/packs/stylesheets/decidim/enhanced_textwork/paragraphs/_preview.scss +3 -0
  182. data/app/permissions/decidim/enhanced_textwork/admin/permissions.rb +147 -0
  183. data/app/permissions/decidim/enhanced_textwork/permissions.rb +163 -0
  184. data/app/presenters/decidim/enhanced_textwork/admin_log/paragraph_note_presenter.rb +39 -0
  185. data/app/presenters/decidim/enhanced_textwork/admin_log/paragraph_presenter.rb +51 -0
  186. data/app/presenters/decidim/enhanced_textwork/admin_log/valuation_assignment_presenter.rb +51 -0
  187. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/paragraph_state_presenter.rb +17 -0
  188. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/paragraph_title_body_presenter.rb +23 -0
  189. data/app/presenters/decidim/enhanced_textwork/admin_log/value_types/valuator_role_user_presenter.rb +19 -0
  190. data/app/presenters/decidim/enhanced_textwork/collaborative_draft_presenter.rb +25 -0
  191. data/app/presenters/decidim/enhanced_textwork/log/resource_presenter.rb +22 -0
  192. data/app/presenters/decidim/enhanced_textwork/log/valuation_assignment_presenter.rb +22 -0
  193. data/app/presenters/decidim/enhanced_textwork/official_author_presenter.rb +14 -0
  194. data/app/presenters/decidim/enhanced_textwork/paragraph_presenter.rb +146 -0
  195. data/app/queries/decidim/enhanced_textwork/filtered_paragraphs.rb +37 -0
  196. data/app/queries/decidim/enhanced_textwork/metrics/accepted_paragraphs_metric_manage.rb +32 -0
  197. data/app/queries/decidim/enhanced_textwork/metrics/endorsements_metric_manage.rb +58 -0
  198. data/app/queries/decidim/enhanced_textwork/metrics/paragraph_followers_metric_measure.rb +58 -0
  199. data/app/queries/decidim/enhanced_textwork/metrics/paragraph_participants_metric_measure.rb +74 -0
  200. data/app/queries/decidim/enhanced_textwork/metrics/paragraphs_metric_manage.rb +48 -0
  201. data/app/queries/decidim/enhanced_textwork/metrics/votes_metric_manage.rb +52 -0
  202. data/app/queries/decidim/enhanced_textwork/similar_paragraphs.rb +67 -0
  203. data/app/services/decidim/enhanced_textwork/collaborative_draft_search.rb +59 -0
  204. data/app/services/decidim/enhanced_textwork/diff_renderer.rb +74 -0
  205. data/app/services/decidim/enhanced_textwork/paragraph_builder.rb +132 -0
  206. data/app/services/decidim/enhanced_textwork/paragraph_search.rb +85 -0
  207. data/app/validators/paragraph_length_validator.rb +40 -0
  208. data/app/views/decidim/enhanced_textwork/admin/paragraph_answers/_form.html.erb +35 -0
  209. data/app/views/decidim/enhanced_textwork/admin/paragraph_notes/_form.html.erb +8 -0
  210. data/app/views/decidim/enhanced_textwork/admin/paragraph_notes/_paragraph_notes.html.erb +45 -0
  211. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_bulk-actions.html.erb +33 -0
  212. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_form.html.erb +101 -0
  213. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_js-callout.html.erb +6 -0
  214. data/app/views/decidim/enhanced_textwork/admin/paragraphs/_paragraph-tr.html.erb +76 -0
  215. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_assign_to_valuator.html.erb +15 -0
  216. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_dropdown.html.erb +56 -0
  217. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_merge.html.erb +15 -0
  218. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_publish_answers.html.erb +14 -0
  219. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_recategorize.html.erb +15 -0
  220. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_scope-change.html.erb +25 -0
  221. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_split.html.erb +15 -0
  222. data/app/views/decidim/enhanced_textwork/admin/paragraphs/bulk_actions/_unassign_from_valuator.html.erb +15 -0
  223. data/app/views/decidim/enhanced_textwork/admin/paragraphs/edit.html.erb +7 -0
  224. data/app/views/decidim/enhanced_textwork/admin/paragraphs/index.html.erb +84 -0
  225. data/app/views/decidim/enhanced_textwork/admin/paragraphs/new.html.erb +7 -0
  226. data/app/views/decidim/enhanced_textwork/admin/paragraphs/publish_answers.js.erb +12 -0
  227. data/app/views/decidim/enhanced_textwork/admin/paragraphs/show.html.erb +186 -0
  228. data/app/views/decidim/enhanced_textwork/admin/paragraphs/update_category.js.erb +26 -0
  229. data/app/views/decidim/enhanced_textwork/admin/paragraphs/update_scope.js.erb +27 -0
  230. data/app/views/decidim/enhanced_textwork/admin/paragraphs_imports/new.html.erb +37 -0
  231. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/_article-preview.html.erb +16 -0
  232. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/_bulk-actions.html.erb +3 -0
  233. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/index.html.erb +55 -0
  234. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/new_editor.html.erb +39 -0
  235. data/app/views/decidim/enhanced_textwork/admin/participatory_texts/new_import.html.erb +39 -0
  236. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_accept_request_access_form.html.erb +8 -0
  237. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_collaborative_drafts.html.erb +16 -0
  238. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_collaborator_requests.html.erb +20 -0
  239. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_count.html.erb +1 -0
  240. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_edit_form_fields.html.erb +83 -0
  241. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_filters.html.erb +32 -0
  242. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_filters_small_view.html.erb +18 -0
  243. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_new_collaborative_draft_button.html.erb +11 -0
  244. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_reject_request_access_form.html.erb +10 -0
  245. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_request_access_form.html.erb +7 -0
  246. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_wizard_aside.html.erb +13 -0
  247. data/app/views/decidim/enhanced_textwork/collaborative_drafts/_wizard_header.html.erb +14 -0
  248. data/app/views/decidim/enhanced_textwork/collaborative_drafts/edit.html.erb +31 -0
  249. data/app/views/decidim/enhanced_textwork/collaborative_drafts/index.html.erb +23 -0
  250. data/app/views/decidim/enhanced_textwork/collaborative_drafts/index.js.erb +10 -0
  251. data/app/views/decidim/enhanced_textwork/collaborative_drafts/new.html.erb +24 -0
  252. data/app/views/decidim/enhanced_textwork/collaborative_drafts/show.html.erb +128 -0
  253. data/app/views/decidim/enhanced_textwork/paragraph_votes/update_buttons_and_counters.js.erb +41 -0
  254. data/app/views/decidim/enhanced_textwork/paragraphs/_count.html.erb +1 -0
  255. data/app/views/decidim/enhanced_textwork/paragraphs/_dynamic_map_instructions.html.erb +4 -0
  256. data/app/views/decidim/enhanced_textwork/paragraphs/_edit_form_fields.html.erb +115 -0
  257. data/app/views/decidim/enhanced_textwork/paragraphs/_endorsements_card_row.html.erb +0 -0
  258. data/app/views/decidim/enhanced_textwork/paragraphs/_filters.html.erb +48 -0
  259. data/app/views/decidim/enhanced_textwork/paragraphs/_filters_small_view.html.erb +18 -0
  260. data/app/views/decidim/enhanced_textwork/paragraphs/_linked_paragraphs.html.erb +34 -0
  261. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph.html.erb +1 -0
  262. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph_badge.html.erb +3 -0
  263. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraph_similar.html.erb +22 -0
  264. data/app/views/decidim/enhanced_textwork/paragraphs/_paragraphs.html.erb +46 -0
  265. data/app/views/decidim/enhanced_textwork/paragraphs/_remaining_votes_count.html.erb +3 -0
  266. data/app/views/decidim/enhanced_textwork/paragraphs/_vote_button.html.erb +61 -0
  267. data/app/views/decidim/enhanced_textwork/paragraphs/_votes_count.html.erb +18 -0
  268. data/app/views/decidim/enhanced_textwork/paragraphs/_voting_rules.html.erb +50 -0
  269. data/app/views/decidim/enhanced_textwork/paragraphs/_wizard_aside.html.erb +20 -0
  270. data/app/views/decidim/enhanced_textwork/paragraphs/_wizard_header.html.erb +42 -0
  271. data/app/views/decidim/enhanced_textwork/paragraphs/compare.html.erb +23 -0
  272. data/app/views/decidim/enhanced_textwork/paragraphs/complete.html.erb +24 -0
  273. data/app/views/decidim/enhanced_textwork/paragraphs/edit.html.erb +31 -0
  274. data/app/views/decidim/enhanced_textwork/paragraphs/edit_draft.html.erb +26 -0
  275. data/app/views/decidim/enhanced_textwork/paragraphs/index.html.erb +56 -0
  276. data/app/views/decidim/enhanced_textwork/paragraphs/index.js.erb +10 -0
  277. data/app/views/decidim/enhanced_textwork/paragraphs/new.html.erb +38 -0
  278. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_index.html.erb +20 -0
  279. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_overview.html.erb +35 -0
  280. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_vote_button.html.erb +53 -0
  281. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_vote_button_chevron.html.erb +72 -0
  282. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_paragraph_votes_count.html.erb +41 -0
  283. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/_view_index.html.erb +10 -0
  284. data/app/views/decidim/enhanced_textwork/paragraphs/participatory_texts/participatory_text.html.erb +29 -0
  285. data/app/views/decidim/enhanced_textwork/paragraphs/preview.html.erb +41 -0
  286. data/app/views/decidim/enhanced_textwork/paragraphs/show.html.erb +143 -0
  287. data/app/views/decidim/enhanced_textwork/versions/index.html.erb +16 -0
  288. data/app/views/decidim/enhanced_textwork/versions/show.html.erb +18 -0
  289. data/config/assets.rb +10 -0
  290. data/config/locales/de.yml +927 -0
  291. data/config/locales/en.yml +967 -0
  292. data/config/locales/todo/am-ET.yml +1 -0
  293. data/config/locales/todo/ar-SA.yml +801 -0
  294. data/config/locales/todo/ar.yml +791 -0
  295. data/config/locales/todo/bg-BG.yml +237 -0
  296. data/config/locales/todo/bg.yml +238 -0
  297. data/config/locales/todo/ca.yml +908 -0
  298. data/config/locales/todo/cs-CZ.yml +787 -0
  299. data/config/locales/todo/cs.yml +969 -0
  300. data/config/locales/todo/da-DK.yml +1 -0
  301. data/config/locales/todo/da.yml +1 -0
  302. data/config/locales/todo/el-GR.yml +1 -0
  303. data/config/locales/todo/el.yml +848 -0
  304. data/config/locales/todo/eo-UY.yml +1 -0
  305. data/config/locales/todo/eo.yml +1 -0
  306. data/config/locales/todo/es-MX.yml +908 -0
  307. data/config/locales/todo/es-PY.yml +908 -0
  308. data/config/locales/todo/es.yml +908 -0
  309. data/config/locales/todo/et-EE.yml +1 -0
  310. data/config/locales/todo/et.yml +1 -0
  311. data/config/locales/todo/eu.yml +717 -0
  312. data/config/locales/todo/fi-pl.yml +763 -0
  313. data/config/locales/todo/fi-plain.yml +920 -0
  314. data/config/locales/todo/fi.yml +920 -0
  315. data/config/locales/todo/fr-CA.yml +936 -0
  316. data/config/locales/todo/fr-LU.yml +903 -0
  317. data/config/locales/todo/fr.yml +936 -0
  318. data/config/locales/todo/ga-IE.yml +275 -0
  319. data/config/locales/todo/gl.yml +808 -0
  320. data/config/locales/todo/hr-HR.yml +1 -0
  321. data/config/locales/todo/hr.yml +1 -0
  322. data/config/locales/todo/hu.yml +847 -0
  323. data/config/locales/todo/id-ID.yml +704 -0
  324. data/config/locales/todo/is-IS.yml +269 -0
  325. data/config/locales/todo/is.yml +274 -0
  326. data/config/locales/todo/it.yml +908 -0
  327. data/config/locales/todo/ja.yml +922 -0
  328. data/config/locales/todo/ko-KR.yml +1 -0
  329. data/config/locales/todo/ko.yml +1 -0
  330. data/config/locales/todo/lb-LU.yml +1 -0
  331. data/config/locales/todo/lb.yml +40 -0
  332. data/config/locales/todo/lt-LT.yml +1 -0
  333. data/config/locales/todo/lt.yml +1 -0
  334. data/config/locales/todo/lv.yml +838 -0
  335. data/config/locales/todo/mt-MT.yml +1 -0
  336. data/config/locales/todo/mt.yml +1 -0
  337. data/config/locales/todo/nl.yml +882 -0
  338. data/config/locales/todo/no.yml +770 -0
  339. data/config/locales/todo/om-ET.yml +1 -0
  340. data/config/locales/todo/pl.yml +927 -0
  341. data/config/locales/todo/pt-BR.yml +908 -0
  342. data/config/locales/todo/pt.yml +945 -0
  343. data/config/locales/todo/ro-RO.yml +886 -0
  344. data/config/locales/todo/ru.yml +379 -0
  345. data/config/locales/todo/si-LK.yml +1 -0
  346. data/config/locales/todo/sk-SK.yml +896 -0
  347. data/config/locales/todo/sk.yml +851 -0
  348. data/config/locales/todo/sl.yml +26 -0
  349. data/config/locales/todo/so-SO.yml +1 -0
  350. data/config/locales/todo/sr-CS.yml +125 -0
  351. data/config/locales/todo/sv.yml +908 -0
  352. data/config/locales/todo/sw-KE.yml +1 -0
  353. data/config/locales/todo/ti-ER.yml +1 -0
  354. data/config/locales/todo/tr-TR.yml +890 -0
  355. data/config/locales/todo/uk.yml +379 -0
  356. data/config/locales/todo/vi-VN.yml +1 -0
  357. data/config/locales/todo/vi.yml +1 -0
  358. data/config/locales/todo/zh-CN.yml +857 -0
  359. data/config/locales/todo/zh-TW.yml +1 -0
  360. data/db/migrate/20161212110850_create_decidim_paragraphs.rb +16 -0
  361. data/db/migrate/20170112115253_create_paragraph_votes.rb +14 -0
  362. data/db/migrate/20170113114245_add_enhanced_textwork_text_search_indexes.rb +8 -0
  363. data/db/migrate/20170118120151_add_counter_cache_votes_to_paragraphs.rb +7 -0
  364. data/db/migrate/20170120151202_add_user_group_id_to_paragraphs.rb +7 -0
  365. data/db/migrate/20170131092413_add_answers_to_paragraphs.rb +9 -0
  366. data/db/migrate/20170205082832_add_index_to_decidim_enhanced_textwork_paragraphs_paragraph_votes_count.rb +9 -0
  367. data/db/migrate/20170215113152_create_paragraph_reports.rb +16 -0
  368. data/db/migrate/20170215131720_add_report_count_to_paragraphs.rb +7 -0
  369. data/db/migrate/20170215132030_add_reference_to_paragraphs.rb +13 -0
  370. data/db/migrate/20170220152416_add_hidden_at_to_paragraphs.rb +7 -0
  371. data/db/migrate/20170228105156_add_geolocalization_fields_to_paragraphs.rb +9 -0
  372. data/db/migrate/20170307085300_migrate_paragraph_reports_data_to_reports.rb +24 -0
  373. data/db/migrate/20170410073742_remove_not_null_reference_paragraphs.rb +7 -0
  374. data/db/migrate/20170612101809_migrate_paragraphs_category.rb +15 -0
  375. data/db/migrate/20171201115434_create_paragraph_endorsements.rb +16 -0
  376. data/db/migrate/20171201122623_add_counter_cache_endorsements_to_paragraphs.rb +8 -0
  377. data/db/migrate/20171212102250_enable_pg_trgm_extension_for_paragraphs.rb +18 -0
  378. data/db/migrate/20171220084719_add_published_at_to_paragraphs.rb +14 -0
  379. data/db/migrate/20180111110204_create_decidim_paragraph_notes.rb +15 -0
  380. data/db/migrate/20180115155220_add_index_created_at_paragraph_notes.rb +7 -0
  381. data/db/migrate/20180305133811_rename_features_to_components_at_paragraphs.rb +11 -0
  382. data/db/migrate/20180326091532_create_decidim_enhanced_textwork_collaborative_drafts.rb +29 -0
  383. data/db/migrate/20180413135249_fix_nil_threshold_per_paragraph.rb +18 -0
  384. data/db/migrate/20180529101323_add_counter_cache_coauthorships_to_paragraphs.rb +8 -0
  385. data/db/migrate/20180529110230_move_enhanced_textwork_authorships_to_coauthorships.rb +28 -0
  386. data/db/migrate/20180529110830_remove_authorships_from_paragraphs.rb +8 -0
  387. data/db/migrate/20180613151121_create_enhanced_textwork_collaborative_draft_collaborator_requests.rb +12 -0
  388. data/db/migrate/20180711074134_add_enhanced_textwork_counter_cache_coauthorships_to_collaborative_drafts.rb +7 -0
  389. data/db/migrate/20180711075004_remove_index_counter_cache_coauthorships_to_paragraphs.rb +7 -0
  390. data/db/migrate/20180927111721_create_enhanced_textwork_participatory_texts.rb +13 -0
  391. data/db/migrate/20180930125321_add_participatory_text_level_to_paragraphs.rb +7 -0
  392. data/db/migrate/20180930125321_add_position_to_paragraphs.rb +7 -0
  393. data/db/migrate/20181003074440_fix_user_groups_ids_in_paragraphs_endorsements.rb +20 -0
  394. data/db/migrate/20181010114622_add_enhanced_textwork_temporary_votes.rb +9 -0
  395. data/db/migrate/20181016132225_add_enhanced_textwork_organization_as_author.rb +13 -0
  396. data/db/migrate/20181017084221_make_author_polymorhpic_for_paragraph_endorsements.rb +31 -0
  397. data/db/migrate/20181026073215_add_enhanced_textwork_created_in_meeting.rb +7 -0
  398. data/db/migrate/20190215113158_use_enhanced_textwork_md5_indexes.rb +17 -0
  399. data/db/migrate/20191206154128_add_endorsements_counter_cache_to_paragraphs.rb +7 -0
  400. data/db/migrate/20200120215928_move_paragraph_endorsements_to_core_endorsements.rb +54 -0
  401. data/db/migrate/20200120230130_drop_paragraph_endorsements.rb +8 -0
  402. data/db/migrate/20200203111239_add_paragraph_valuation_assignments.rb +12 -0
  403. data/db/migrate/20200210135152_add_costs_to_paragraphs.rb +9 -0
  404. data/db/migrate/20200212120110_sync_paragraphs_state_with_amendments_state.rb +28 -0
  405. data/db/migrate/20200227175922_add_state_published_at_to_paragraphs.rb +7 -0
  406. data/db/migrate/20200306123652_publish_existing_paragraphs_state.rb +15 -0
  407. data/db/migrate/20200708091228_move_paragraphs_fields_to_i18n.rb +86 -0
  408. data/db/migrate/20200730131631_move_paragraph_endorsed_event_notifications_to_resource_endorsed_event.rb +20 -0
  409. data/db/migrate/20200827154156_add_commentable_counter_cache_to_paragraphs.rb +12 -0
  410. data/db/migrate/20201002085508_fix_paragraphs_data.rb +36 -0
  411. data/db/migrate/20210127115628_fix_answered_paragraphs_after_copy.rb +14 -0
  412. data/db/migrate/20210310102839_add_followable_counter_cache_to_paragraphs.rb +16 -0
  413. data/db/migrate/20210310120812_add_enhanced_textwork_followable_counter_cache_to_collaborative_drafts.rb +16 -0
  414. data/db/migrate/20210318082934_fix_counters_for_copied_paragraphs.rb +19 -0
  415. data/lib/decidim/api/paragraph_input_filter.rb +29 -0
  416. data/lib/decidim/api/paragraph_input_sort.rb +20 -0
  417. data/lib/decidim/api/paragraph_type.rb +56 -0
  418. data/lib/decidim/api/paragraphs_type.rb +43 -0
  419. data/lib/decidim/content_parsers/paragraph_parser.rb +101 -0
  420. data/lib/decidim/content_renderers/paragraph_renderer.rb +33 -0
  421. data/lib/decidim/enhanced_textwork/admin.rb +10 -0
  422. data/lib/decidim/enhanced_textwork/admin_engine.rb +52 -0
  423. data/lib/decidim/enhanced_textwork/api.rb +10 -0
  424. data/lib/decidim/enhanced_textwork/commentable_collaborative_draft.rb +38 -0
  425. data/lib/decidim/enhanced_textwork/commentable_paragraph.rb +36 -0
  426. data/lib/decidim/enhanced_textwork/component.rb +448 -0
  427. data/lib/decidim/enhanced_textwork/doc_to_markdown.rb +50 -0
  428. data/lib/decidim/enhanced_textwork/engine.rb +204 -0
  429. data/lib/decidim/enhanced_textwork/html_to_markdown.rb +22 -0
  430. data/lib/decidim/enhanced_textwork/markdown_to_paragraphs.rb +153 -0
  431. data/lib/decidim/enhanced_textwork/odt_to_markdown.rb +46 -0
  432. data/lib/decidim/enhanced_textwork/paragraph_creator.rb +98 -0
  433. data/lib/decidim/enhanced_textwork/paragraph_serializer.rb +95 -0
  434. data/lib/decidim/enhanced_textwork/participatory_text_section.rb +21 -0
  435. data/lib/decidim/enhanced_textwork/test/capybara_paragraphs_picker.rb +59 -0
  436. data/lib/decidim/enhanced_textwork/test/factories.rb +492 -0
  437. data/lib/decidim/enhanced_textwork/valuatable.rb +21 -0
  438. data/lib/decidim/enhanced_textwork/version.rb +14 -0
  439. data/lib/decidim/enhanced_textwork.rb +58 -0
  440. data/lib/decidim/exporters/word.rb +309 -0
  441. metadata +704 -0
@@ -0,0 +1,411 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # The data store for a Paragraph in the Decidim::EnhancedTextwork component.
6
+ class Paragraph < EnhancedTextwork::ApplicationRecord
7
+ include Decidim::Resourceable
8
+ include Decidim::Coauthorable
9
+ include Decidim::HasComponent
10
+ include Decidim::ScopableResource
11
+ include Decidim::HasReference
12
+ include Decidim::HasCategory
13
+ include Decidim::Reportable
14
+ include Decidim::HasAttachments
15
+ include Decidim::Followable
16
+ include Decidim::EnhancedTextwork::CommentableParagraph
17
+ include Decidim::Searchable
18
+ include Decidim::Traceable
19
+ include Decidim::Loggable
20
+ include Decidim::Fingerprintable
21
+ include Decidim::DataPortability
22
+ include Decidim::EnhancedTextwork::ParticipatoryTextSection
23
+ include Decidim::Amendable
24
+ include Decidim::NewsletterParticipant
25
+ include Decidim::Randomable
26
+ include Decidim::Endorsable
27
+ include Decidim::EnhancedTextwork::Valuatable
28
+ include Decidim::TranslatableResource
29
+ include Decidim::TranslatableAttributes
30
+
31
+ translatable_fields :title, :body
32
+
33
+ POSSIBLE_STATES = %w(not_answered evaluating accepted rejected withdrawn).freeze
34
+
35
+ fingerprint fields: [:title, :body]
36
+
37
+ amendable(
38
+ fields: [:title, :body],
39
+ form: "Decidim::EnhancedTextwork::ParagraphForm"
40
+ )
41
+
42
+ component_manifest_name "enhanced_textwork"
43
+
44
+ has_many :votes,
45
+ -> { final },
46
+ foreign_key: "decidim_paragraph_id",
47
+ class_name: "Decidim::EnhancedTextwork::ParagraphVote",
48
+ dependent: :destroy,
49
+ counter_cache: "paragraph_votes_count"
50
+
51
+ has_many :notes, foreign_key: "decidim_paragraph_id", class_name: "ParagraphNote", dependent: :destroy, counter_cache: "paragraph_notes_count"
52
+
53
+ validates :title, :body, presence: true
54
+
55
+ geocoded_by :address
56
+
57
+ scope :answered, -> { where.not(answered_at: nil) }
58
+ scope :not_answered, -> { where(answered_at: nil) }
59
+
60
+ scope :state_not_published, -> { where(state_published_at: nil) }
61
+ scope :state_published, -> { where.not(state_published_at: nil).where.not(state: nil) }
62
+
63
+ scope :accepted, -> { state_published.where(state: "accepted") }
64
+ scope :rejected, -> { state_published.where(state: "rejected") }
65
+ scope :evaluating, -> { state_published.where(state: "evaluating") }
66
+ scope :withdrawn, -> { where(state: "withdrawn") }
67
+ scope :except_rejected, -> { where.not(state: "rejected").or(state_not_published) }
68
+ scope :except_withdrawn, -> { where.not(state: "withdrawn").or(where(state: nil)) }
69
+ scope :drafts, -> { where(published_at: nil) }
70
+ scope :except_drafts, -> { where.not(published_at: nil) }
71
+ scope :published, -> { where.not(published_at: nil) }
72
+ scope :order_by_most_recent, -> { order(created_at: :desc) }
73
+ scope :sort_by_valuation_assignments_count_asc, lambda {
74
+ order("#{sort_by_valuation_assignments_count_nulls_last_query}ASC NULLS FIRST")
75
+ }
76
+
77
+ scope :sort_by_valuation_assignments_count_desc, lambda {
78
+ order("#{sort_by_valuation_assignments_count_nulls_last_query}DESC NULLS LAST")
79
+ }
80
+
81
+ def self.with_valuation_assigned_to(user, space)
82
+ valuator_roles = space.user_roles(:valuator).where(user: user)
83
+
84
+ includes(:valuation_assignments)
85
+ .where(decidim_enhanced_textwork_valuation_assignments: { valuator_role_id: valuator_roles })
86
+ end
87
+
88
+ acts_as_list scope: :decidim_component_id
89
+
90
+ searchable_fields({
91
+ scope_id: :decidim_scope_id,
92
+ participatory_space: { component: :participatory_space },
93
+ D: :body,
94
+ A: :title,
95
+ datetime: :published_at
96
+ },
97
+ index_on_create: ->(paragraph) { paragraph.official? },
98
+ index_on_update: ->(paragraph) { paragraph.visible? })
99
+
100
+ def self.log_presenter_class_for(_log)
101
+ Decidim::EnhancedTextwork::AdminLog::ParagraphPresenter
102
+ end
103
+
104
+ # Returns a collection scoped by an author.
105
+ # Overrides this method in DataPortability to support Coauthorable.
106
+ def self.user_collection(author)
107
+ return unless author.is_a?(Decidim::User)
108
+
109
+ joins(:coauthorships)
110
+ .where(decidim_coauthorships: { coauthorable_type: name })
111
+ .where("decidim_coauthorships.decidim_author_id = ? AND decidim_coauthorships.decidim_author_type = ? ", author.id, author.class.base_class.name)
112
+ end
113
+
114
+ def self.retrieve_paragraphs_for(component)
115
+ Decidim::EnhancedTextwork::Paragraph.where(component: component).joins(:coauthorships)
116
+ .includes(:votes, :endorsements)
117
+ .where(decidim_coauthorships: { decidim_author_type: "Decidim::UserBaseEntity" })
118
+ .not_hidden
119
+ .published
120
+ .except_withdrawn
121
+ end
122
+
123
+ def self.newsletter_participant_ids(component)
124
+ paragraphs = retrieve_paragraphs_for(component).uniq
125
+
126
+ coauthors_recipients_ids = paragraphs.map { |p| p.notifiable_identities.pluck(:id) }.flatten.compact.uniq
127
+
128
+ participants_has_voted_ids = Decidim::EnhancedTextwork::ParagraphVote.joins(:paragraph).where(paragraph: paragraphs).joins(:author).map(&:decidim_author_id).flatten.compact.uniq
129
+
130
+ endorsements_participants_ids = Decidim::Endorsement.where(resource: paragraphs)
131
+ .where(decidim_author_type: "Decidim::UserBaseEntity")
132
+ .pluck(:decidim_author_id).to_a.compact.uniq
133
+
134
+ commentators_ids = Decidim::Comments::Comment.user_commentators_ids_in(paragraphs)
135
+
136
+ (endorsements_participants_ids + participants_has_voted_ids + coauthors_recipients_ids + commentators_ids).flatten.compact.uniq
137
+ end
138
+
139
+ # Public: Updates the vote count of this paragraph.
140
+ #
141
+ # Returns nothing.
142
+ # rubocop:disable Rails/SkipsModelValidations
143
+ def update_votes_count
144
+ update_columns(paragraph_votes_count: votes.count)
145
+ end
146
+ # rubocop:enable Rails/SkipsModelValidations
147
+
148
+ # Public: Check if the user has voted the paragraph.
149
+ #
150
+ # Returns Boolean.
151
+ def voted_by?(user)
152
+ ParagraphVote.where(paragraph: self, author: user).any?
153
+ end
154
+
155
+ # Public: Checks if the paragraph has been published or not.
156
+ #
157
+ # Returns Boolean.
158
+ def published?
159
+ published_at.present?
160
+ end
161
+
162
+ # Public: Returns the published state of the paragraph.
163
+ #
164
+ # Returns Boolean.
165
+ def state
166
+ return amendment.state if emendation?
167
+ return nil unless published_state? || withdrawn?
168
+
169
+ super
170
+ end
171
+
172
+ # This is only used to define the setter, as the getter will be overriden below.
173
+ alias_attribute :internal_state, :state
174
+
175
+ # Public: Returns the internal state of the paragraph.
176
+ #
177
+ # Returns Boolean.
178
+ def internal_state
179
+ return amendment.state if emendation?
180
+
181
+ self[:state]
182
+ end
183
+
184
+ # Public: Checks if the organization has published the state for the paragraph.
185
+ #
186
+ # Returns Boolean.
187
+ def published_state?
188
+ emendation? || state_published_at.present?
189
+ end
190
+
191
+ # Public: Checks if the organization has given an answer for the paragraph.
192
+ #
193
+ # Returns Boolean.
194
+ def answered?
195
+ answered_at.present?
196
+ end
197
+
198
+ # Public: Checks if the author has withdrawn the paragraph.
199
+ #
200
+ # Returns Boolean.
201
+ def withdrawn?
202
+ internal_state == "withdrawn"
203
+ end
204
+
205
+ # Public: Checks if the organization has accepted a paragraph.
206
+ #
207
+ # Returns Boolean.
208
+ def accepted?
209
+ state == "accepted"
210
+ end
211
+
212
+ # Public: Checks if the organization has rejected a paragraph.
213
+ #
214
+ # Returns Boolean.
215
+ def rejected?
216
+ state == "rejected"
217
+ end
218
+
219
+ # Public: Checks if the organization has marked the paragraph as evaluating it.
220
+ #
221
+ # Returns Boolean.
222
+ def evaluating?
223
+ state == "evaluating"
224
+ end
225
+
226
+ # Public: Overrides the `reported_content_url` Reportable concern method.
227
+ def reported_content_url
228
+ ResourceLocatorPresenter.new(self).url
229
+ end
230
+
231
+ # Public: Overrides the `reported_attributes` Reportable concern method.
232
+ def reported_attributes
233
+ [:title, :body]
234
+ end
235
+
236
+ # Public: Overrides the `reported_searchable_content_extras` Reportable concern method.
237
+ def reported_searchable_content_extras
238
+ [authors.map(&:name).join("\n")]
239
+ end
240
+
241
+ # Public: Whether the paragraph is official or not.
242
+ def official?
243
+ authors.first.is_a?(Decidim::Organization)
244
+ end
245
+
246
+ # Public: Whether the paragraph is created in a meeting or not.
247
+ def official_meeting?
248
+ authors.first.class.name == "Decidim::Meetings::Meeting"
249
+ end
250
+
251
+ # Public: The maximum amount of votes allowed for this paragraph.
252
+ #
253
+ # Returns an Integer with the maximum amount of votes, nil otherwise.
254
+ def maximum_votes
255
+ maximum_votes = component.settings.threshold_per_paragraph
256
+ return nil if maximum_votes.zero?
257
+
258
+ maximum_votes
259
+ end
260
+
261
+ # Public: The maximum amount of votes allowed for this paragraph. 0 means infinite.
262
+ #
263
+ # Returns true if reached, false otherwise.
264
+ def maximum_votes_reached?
265
+ return false unless maximum_votes
266
+
267
+ votes.count >= maximum_votes
268
+ end
269
+
270
+ # Public: Can accumulate more votres than maximum for this paragraph.
271
+ #
272
+ # Returns true if can accumulate, false otherwise
273
+ def can_accumulate_supports_beyond_threshold
274
+ component.settings.can_accumulate_supports_beyond_threshold
275
+ end
276
+
277
+ # Checks whether the user can edit the given paragraph.
278
+ #
279
+ # user - the user to check for authorship
280
+ def editable_by?(user)
281
+ return true if draft?
282
+
283
+ !published_state? && within_edit_time_limit? && !copied_from_other_component? && created_by?(user)
284
+ end
285
+
286
+ # Checks whether the user can withdraw the given paragraph.
287
+ #
288
+ # user - the user to check for withdrawability.
289
+ def withdrawable_by?(user)
290
+ user && !withdrawn? && authored_by?(user) && !copied_from_other_component?
291
+ end
292
+
293
+ # Public: Whether the paragraph is a draft or not.
294
+ def draft?
295
+ published_at.nil?
296
+ end
297
+
298
+ # Defines the base query so that ransack can actually sort by this value
299
+ def self.sort_by_valuation_assignments_count_nulls_last_query
300
+ <<-SQL.squish
301
+ (
302
+ SELECT COUNT(decidim_enhanced_textwork_valuation_assignments.id)
303
+ FROM decidim_enhanced_textwork_valuation_assignments
304
+ WHERE decidim_enhanced_textwork_valuation_assignments.decidim_paragraph_id = decidim_enhanced_textwork_paragraphs.id
305
+ GROUP BY decidim_enhanced_textwork_valuation_assignments.decidim_paragraph_id
306
+ )
307
+ SQL
308
+ end
309
+
310
+ # method to filter by assigned valuator role ID
311
+ def self.valuator_role_ids_has(value)
312
+ query = <<-SQL.squish
313
+ :value = any(
314
+ (SELECT decidim_enhanced_textwork_valuation_assignments.valuator_role_id
315
+ FROM decidim_enhanced_textwork_valuation_assignments
316
+ WHERE decidim_enhanced_textwork_valuation_assignments.decidim_paragraph_id = decidim_enhanced_textwork_paragraphs.id
317
+ )
318
+ )
319
+ SQL
320
+ where(query, value: value)
321
+ end
322
+
323
+ def self.ransackable_scopes(_auth = nil)
324
+ [:valuator_role_ids_has]
325
+ end
326
+
327
+ ransacker :state_published do
328
+ Arel.sql("CASE
329
+ WHEN EXISTS (
330
+ SELECT 1 FROM decidim_amendments
331
+ WHERE decidim_amendments.decidim_emendation_type = 'Decidim::EnhancedTextwork::Paragraph'
332
+ AND decidim_amendments.decidim_emendation_id = decidim_enhanced_textwork_paragraphs.id
333
+ ) THEN 0
334
+ WHEN state_published_at IS NULL AND answered_at IS NOT NULL THEN 2
335
+ WHEN state_published_at IS NOT NULL THEN 1
336
+ ELSE 0 END
337
+ ")
338
+ end
339
+
340
+ def self.sort_by_translated_title_asc
341
+ field = Arel::Nodes::InfixOperation.new("->>", arel_table[:title], Arel::Nodes.build_quoted(I18n.locale))
342
+ order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("ASC")))
343
+ end
344
+
345
+ def self.sort_by_translated_title_desc
346
+ field = Arel::Nodes::InfixOperation.new("->>", arel_table[:title], Arel::Nodes.build_quoted(I18n.locale))
347
+ order(Arel::Nodes::InfixOperation.new("", field, Arel.sql("DESC")))
348
+ end
349
+
350
+ ransacker :title do
351
+ Arel.sql(%{cast("decidim_enhanced_textwork_paragraphs"."title" as text)})
352
+ end
353
+
354
+ ransacker :id_string do
355
+ Arel.sql(%{cast("decidim_enhanced_textwork_paragraphs"."id" as text)})
356
+ end
357
+
358
+ ransacker :is_emendation do |_parent|
359
+ query = <<-SQL.squish
360
+ (
361
+ SELECT EXISTS (
362
+ SELECT 1 FROM decidim_amendments
363
+ WHERE decidim_amendments.decidim_emendation_type = 'Decidim::EnhancedTextwork::Paragraph'
364
+ AND decidim_amendments.decidim_emendation_id = decidim_enhanced_textwork_paragraphs.id
365
+ )
366
+ )
367
+ SQL
368
+ Arel.sql(query)
369
+ end
370
+
371
+ def self.export_serializer
372
+ Decidim::EnhancedTextwork::ParagraphSerializer
373
+ end
374
+
375
+ def self.data_portability_images(user)
376
+ user_collection(user).map { |p| p.attachments.collect(&:file) }
377
+ end
378
+
379
+ # Public: Overrides the `allow_resource_permissions?` Resourceable concern method.
380
+ def allow_resource_permissions?
381
+ component.settings.resources_permissions_enabled
382
+ end
383
+
384
+ # Checks whether the paragraph is inside the time window to be editable or not once published.
385
+ def within_edit_time_limit?
386
+ return true if draft?
387
+ return true if component.settings.paragraph_edit_time == "infinite"
388
+
389
+ limit = updated_at + component.settings.paragraph_edit_before_minutes.minutes
390
+ Time.current < limit
391
+ end
392
+
393
+ def process_amendment_state_change!
394
+ return unless %w(accepted rejected evaluating withdrawn).member?(amendment.state)
395
+
396
+ PaperTrail.request(enabled: false) do
397
+ update!(
398
+ state: amendment.state,
399
+ state_published_at: Time.current
400
+ )
401
+ end
402
+ end
403
+
404
+ private
405
+
406
+ def copied_from_other_component?
407
+ linked_resources(:paragraphs, "copied_from_component").any?
408
+ end
409
+ end
410
+ end
411
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # A paragraph can include a notes created by admins.
6
+ class ParagraphNote < ApplicationRecord
7
+ include Decidim::Traceable
8
+ include Decidim::Loggable
9
+
10
+ belongs_to :paragraph, foreign_key: "decidim_paragraph_id", class_name: "Decidim::EnhancedTextwork::Paragraph", counter_cache: true
11
+ belongs_to :author, foreign_key: "decidim_author_id", class_name: "Decidim::User"
12
+
13
+ default_scope { order(created_at: :asc) }
14
+
15
+ def self.log_presenter_class_for(_log)
16
+ Decidim::EnhancedTextwork::AdminLog::ParagraphNotePresenter
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # A paragraph can include a vote per user.
6
+ class ParagraphVote < ApplicationRecord
7
+ belongs_to :paragraph, foreign_key: "decidim_paragraph_id", class_name: "Decidim::EnhancedTextwork::Paragraph"
8
+ belongs_to :author, foreign_key: "decidim_author_id", class_name: "Decidim::User"
9
+
10
+ validates :paragraph, uniqueness: { scope: :author }
11
+ validate :author_and_paragraph_same_organization
12
+ validate :paragraph_not_rejected
13
+
14
+ after_save :update_paragraph_votes_count
15
+ after_destroy :update_paragraph_votes_count
16
+
17
+ # Temporary votes are used when a minimum amount of votes is configured in
18
+ # a component. They aren't taken into account unless the amount of votes
19
+ # exceeds a threshold - meanwhile, they're marked as temporary.
20
+ def self.temporary
21
+ where(temporary: true)
22
+ end
23
+
24
+ # Final votes are votes that will be taken into account, that is, they're
25
+ # not temporary.
26
+ def self.final
27
+ where(temporary: false)
28
+ end
29
+
30
+ private
31
+
32
+ def update_paragraph_votes_count
33
+ paragraph.update_votes_count
34
+ end
35
+
36
+ # Private: check if the paragraph and the author have the same organization
37
+ def author_and_paragraph_same_organization
38
+ return if !paragraph || !author
39
+
40
+ errors.add(:paragraph, :invalid) unless author.organization == paragraph.organization
41
+ end
42
+
43
+ def paragraph_not_rejected
44
+ return unless paragraph
45
+
46
+ errors.add(:paragraph, :invalid) if paragraph.rejected?
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # Contains the meta data of the document, like title and description.
6
+ #
7
+ class ParticipatoryText < EnhancedTextwork::ApplicationRecord
8
+ include Decidim::HasComponent
9
+ include Decidim::Traceable
10
+ include Decidim::Loggable
11
+ include Decidim::TranslatableResource
12
+
13
+ translatable_fields :title, :description
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module EnhancedTextwork
5
+ # A valuation assignment links a paragraph and a Valuator user role.
6
+ # Valuators will be users in charge of defining the monetary cost of a
7
+ # paragraph.
8
+ class ValuationAssignment < ApplicationRecord
9
+ include Decidim::Traceable
10
+ include Decidim::Loggable
11
+
12
+ belongs_to :paragraph, foreign_key: "decidim_paragraph_id", class_name: "Decidim::EnhancedTextwork::Paragraph"
13
+ belongs_to :valuator_role, polymorphic: true
14
+
15
+ def self.log_presenter_class_for(_log)
16
+ Decidim::EnhancedTextwork::AdminLog::ValuationAssignmentPresenter
17
+ end
18
+
19
+ def valuator
20
+ valuator_role.user
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,52 @@
1
+ # Section title 1: grouping content
2
+
3
+ Participatory texts relay on the parsing of Markdown texts to produce a structured document.
4
+
5
+ Participatory texts are divided into 3 types of blocks:
6
+ - Section: produced by main headers (paragraphs starting with "# ")
7
+ - Subsection: produced by secondary headers (paragraphs starting more than one "#") until 6 levels.
8
+ - Article: produced by paragraphs and lists.
9
+
10
+ ## Subsection title 1.1
11
+ Parsing of Markdown is strict.
12
+ This means that, for paragraphs and lists, all blocks should be separated by a blank line between them.
13
+ The first, second and this third paragraphs, for example, will be grouped into a single participatory text article.
14
+
15
+ This paragraph instead, will produce a single participatory text article.
16
+
17
+ This paragraph also, will produce a third participatory text article.
18
+
19
+ ## Subsection title 1.2
20
+
21
+ Inside a paragraph list or a list, **bold text** is supported, *italics text* is supported, __underlined text__ is supported.
22
+ As explained [here](https://daringfireball.net/projects/markdown/syntax#em) Markdown treats asterisks (\*) and underscores (\_) as indicators of emphasis. Text wrapped with one \* or \_ will be wrapped with an HTML <em> tag; double \*’s or \_’s will be wrapped with an HTML &lt;strong> tag. E.g., this input:
23
+ - *single asterisks*
24
+ - _single underscores_
25
+ - **double asterisks**
26
+ - __double underscores__
27
+
28
+ You can use the following reference when writing your documents: [https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet).
29
+
30
+ # Section title 2: lists
31
+
32
+ Lists will be parsed as one block:
33
+
34
+ - consensus by simple majority: when a, b, and c appear in the creation.
35
+ - consensus by enhanced majority: when a, b, c and also d appear in the creation.
36
+ - consensus by absolute majority: when x, y and z appear in the creation.
37
+ - consensus by imposing whatever the organization wants: to be used at will.
38
+ - consensus by ignoring whatever resulted from the previous consensus: to be used when organization don't like the results of another consensus system.
39
+
40
+ Ordered lists reset numberings to the correct order (1,2,3,4,5 in this case):
41
+
42
+ 1. one
43
+ 2. two
44
+ 3. three
45
+ 1. four
46
+ 1. five
47
+
48
+ # Section title 3: images and links
49
+
50
+ A link to Decidim's web site uses [this format](https://decidim.org).
51
+
52
+ ![Important image for Decidim](https://meta.decidim.org/assets/decidim/decidim-logo-1f39092fb3e41d23936dc8aeadd054e2119807dccf3c395de88637e4187f0a3f.svg)
@@ -0,0 +1,17 @@
1
+ import "src/decidim/enhanced_textwork/utils"
2
+ import "src/decidim/enhanced_textwork/add_paragraph"
3
+ import "src/decidim/enhanced_textwork/toggle_element.js"
4
+
5
+ // Images
6
+ require.context("../images", true)
7
+
8
+ // Documents
9
+ require.context("../documents", true)
10
+
11
+ // Add proposals-overview class to elements with the class "off-canvas-wrapper"
12
+ $(() => {
13
+ var elements = document.getElementsByClassName("off-canvas-wrapper");
14
+ for (let element of elements) {
15
+ element.classList.add("paragraphs-overview");
16
+ }
17
+ });
@@ -0,0 +1,3 @@
1
+ import "src/decidim/enhanced_textwork/admin/paragraphs"
2
+ import "src/decidim/enhanced_textwork/admin/paragraphs_form"
3
+ import "src/decidim/enhanced_textwork/admin/paragraphs_picker"
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 35 35"><path d="M17.5 35A17.5 17.5 0 1 1 35 17.5 17.52 17.52 0 0 1 17.5 35zm0-33.06A15.56 15.56 0 1 0 33.06 17.5 15.57 15.57 0 0 0 17.5 1.94zm9.5 13.7H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zm0 3.68H8a1 1 0 0 1 0-1.94h19a1 1 0 0 1 0 1.94zM22.26 23H8a1 1 0 0 1 0-1.94h14.26a1 1 0 0 1 0 1.94z"/></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="accepted-svg" width="1080" height="1080" x="0" y="0" enable-background="new 0 0 1080 1080" version="1.1" viewBox="0 0 1080 1080" xml:space="preserve"><g id="accepted" class="stroke-primary"><g id="sleeve_1_"><rect id="_x32_5-pct_3_" width="215" height="286" x="404.5" y="775.5" fill="#31536E" fill-opacity=".25" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" class="fill-primary"/><rect width="215" height="208" x="404.5" y="875.5" fill="#31536E" stroke="#31536E" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" class="fill-primary"/><line x1="431.5" x2="431.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="463.5" x2="463.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="495.5" x2="495.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="527.5" x2="527.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="559.5" x2="559.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="591.5" x2="591.5" y1="775.5" y2="853.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/></g><g><g id="hand_1_"><polygon fill="#31536E" points="423.5 770.5 601.107 770.5 601.107 667.825 658.61 634.993 696.29 599.501 725.957 559.263 725.957 448.536 696.29 447.586 669.706 465.309 638.964 527.5 566.675 560.819 510 516.5 480.5 460.928 557.167 370.5 619.5 404.5 647.629 438.5 684.541 447.184 716.285 430.5 675.5 351.599 569.5 283.836 527.5 287.634 441.5 341.5 366.931 422.676 352.489 461.459 361.5 559.543 413.81 669.5 421.5 698.5" class="fill-primary" opacity=".1"/><path fill="#FFF" d="M727.875,451.459h-20.676c0,0-9.086,51.541,0,53.326s20.505,0,20.505,0"/><path fill="#FFF" d="M695.802,395.398c-10.302,6.279-11.942,16.53-11.052,20.102s16.611,27.104,16.611,27.104l14.924-4.782 L695.802,395.398z"/><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M592.395,671.5c61.525-25.129,97.612-56.398,133.562-112.237c0,0,4.314-90.188,0-110.727 c-19.493,1.786-56.957-21.036-86.993,83.572c-23.964,5.392-52.964,26.559-90,32.964"/><line x1="418.5" x2="418.5" y1="775.5" y2="677.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><line x1="604.5" x2="604.5" y1="669.5" y2="775.5" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16"/><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M572.321,554.571c0,0-87.773-39.071-88.75-93.646c16.068-10.714,63.068-69,73.596-83.286 c10.524,7.143,57.627,28.263,60.368,31.786c12.19,15.667,61.25,56.072,98.75,28.396c-4.465-19.646-24.821-52.679-28.396-60.714 c-3.569-8.035-11.604-22.536-23.214-29.679c-11.604-7.143-60-40.857-85.179-53.357s-49.821-3.571-56.071,0 c-6.25,3.571-99.82,65-129.929,96.25C363.392,421.571,352.5,447.5,352.5,447.5s-2.401,136.587,64.531,226.439"/><path id="_x32_5-pct_4_" fill="#31536E" fill-opacity=".25" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M370.5,418.321c18.5-44.646,59.535-181.464,63.107-193.964c3.569-12.5,30-20,62.143-24.464s94.286-17.429,108.75-19.214 c14.464-1.785,25.179,5.358,43.929,16.072s47.286,23.214,79.446,35.714c-5.34,48.214-30.339,55.876-41.946,55.17 c-11.604-0.706-42.68,4.008-88.215-29.027c0,0-24.464,2.964-87.714,19.036l-3.909,27.584" class="fill-primary"/><path id="_x35_0-pct_3_" fill="#31536E" fill-opacity=".5" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M484.548,201.858C513.608,161.5,573.429,92.286,585.929,79.786c19.646,15.178,47.357,46.428,5.571,100.893" class="fill-primary"/><path fill="#FFF" fill-opacity=".5" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="8" d="M722.875,236.465l-46.55-19.335c-2.54,8.62-13.532,24.692,0,27.37s43.572,8.656,43.572,8.656L722.875,236.465z"/><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="8" d="M707.199,451.459c0,0-9.086,51.541,0,53.326s20.505,0,20.505,0"/><path fill="#FFF" fill-opacity=".5" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="8" d="M586.929,84.786l-26.049,30.076c9.979,9.209,16.312,10.862,20.787,4c3.773-5.786,3.806-6.09,17.079-21.401L586.929,84.786z"/></g></g><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M522.011,422.676c1.989,14.646,6.312,40.896,1.85,41.788c6.25,9.822,27.142,45.127,24.643,73.036"/><path id="_x35_0-pct" fill="#31536E" fill-opacity=".5" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M522.011,422.676c1.989,14.646,6.312,40.896,1.85,41.788c6.25,9.822,27.142,45.127,24.643,73.036l-45.705-31.921l-19.225-44.651 L522.011,422.676z" class="fill-primary"/><line x1="525.678" x2="523.429" y1="273.6" y2="294.071" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" opacity=".1"/><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="8" d="M695.802,395.398c-10.302,6.279-11.942,16.53-11.052,20.102s16.611,27.104,16.611,27.104"/><line x1="638.964" x2="656.295" y1="532.108" y2="550.628" fill="none" stroke="#31536E" stroke-linecap="round" stroke-miterlimit="10" stroke-width="8"/><line x1="557.167" x2="557.167" y1="377.642" y2="351.599" fill="none" stroke="#31536E" stroke-linecap="round" stroke-miterlimit="10" stroke-width="8"/><line x1="597.714" x2="604.5" y1="252.608" y2="231.143" fill="none" stroke="#31536E" stroke-linecap="round" stroke-miterlimit="10" stroke-width="8"/><line x1="483.571" x2="455.093" y1="460.928" y2="461.459" fill="none" stroke="#31536E" stroke-linecap="round" stroke-miterlimit="10" stroke-width="8"/><line x1="510" x2="495.591" y1="277.644" y2="264.603" fill="none" stroke="#31536E" stroke-linecap="round" stroke-miterlimit="10" stroke-width="8"/><g id="stars_3" class="stars"><path fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4" d="M178.645,872.483c0-14.688-18.667-35.354-35.355-35.354c15.355-0.001,35.355-20.334,35.355-35.356 c0,15.022,16.667,35.355,35.355,35.355C194.978,837.129,178.645,857.796,178.645,872.483z"/><g><circle cx="267.833" cy="219.444" r="13.5" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="268" x2="268" y1="195.944" y2="165.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="268" x2="268" y1="243.944" y2="273.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="291" x2="321" y1="219.944" y2="219.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="244" x2="214" y1="219.944" y2="219.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="878.875" x2="852.713" y1="649.072" y2="675.234" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="843.521" x2="817.357" y1="684.429" y2="710.592" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="878.168" x2="852.005" y1="710.592" y2="684.429" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="842.813" x2="816.65" y1="675.234" y2="649.072" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><path fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4" d="M488.591,88.553c0,0-24.603,4.604-30.249,10.249c-5.646,5.646-10.249,30.249-10.249,30.249s-4.603-24.603-10.249-30.249 c-5.646-5.646-30.249-10.249-30.249-10.249s25.188-5.187,30.249-10.249c5.062-5.062,10.249-30.249,10.249-30.249 s4.604,24.603,10.249,30.249C463.988,83.95,488.591,88.553,488.591,88.553z"/><g><circle cx="814.929" cy="165.944" r="18.5" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="774.929" cy="165.944" r="7.166" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="814.929" cy="205.944" r="7.166" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="854.929" cy="165.944" r="7.166" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="814.929" cy="125.944" r="7.166" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="133.832" x2="188.735" y1="444.075" y2="498.98" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="188.735" x2="133.832" y1="444.075" y2="498.98" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="143.086" x2="116.086" y1="471.103" y2="471.103" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="181.086" x2="208.086" y1="471.103" y2="471.103" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="162.086" x2="162.086" y1="490.103" y2="517.103" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="162.086" x2="162.086" y1="452.103" y2="425.103" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="912.5" x2="912.5" y1="845.944" y2="924.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="951.5" x2="872.5" y1="885.944" y2="885.944" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="892.5" cy="905.444" r="7.039" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="892.5" cy="865.444" r="7.039" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="932.5" cy="905.444" r="7.039" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="932.5" cy="865.444" r="7.039" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g></g></g></svg>
@@ -0,0 +1 @@
1
+ <svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" id="supports-svg" width="1080" height="1080" x="0" y="0" enable-background="new 0 0 1080 1080" version="1.1" viewBox="0 0 1080 1080" xml:space="preserve"><g id="supports" class="stroke-primary"><g id="thumb-up"><rect id="_x35_0-pct_10_" width="169.596" height="357.296" x="269.861" y="593.333" fill="#31536E" fill-opacity=".5" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" class="fill-primary"/><path fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="16" d="M441.917,625.219c77.063,0,110.925-67.804,117.19-105.751c5.192-31.435-0.575-127.921-0.575-127.921s86.541-11.506,92.469,53.694 c5.927,65.199,1.793,176.676,1.793,176.676h-65.201l156.71,1.21c0,0,64.839-6.822,64.839,43.559c0,50.387,0,155.638,0,207.458 c0,63.782-2.858,76.485-57.391,76.485c-38.522,0-184.904,0-223.43,0c-38.53,0-44.453-30.489-44.453-30.489h-39.646"/><g><path id="_x32_5-pct_10_" fill="#31536E" fill-opacity=".25" d="M751.75,893.462c-38.522,0-184.904,0-223.43,0 c-38.53,0-44.453-30.489-44.453-30.489h-39.646l-1.858-237.761c-0.149,0.001-0.296,0.007-0.446,0.007l2.305,294.921h39.646 c0,0,5.922,30.489,44.453,30.489c38.526,0,184.908,0,223.43,0c54.532,0,57.391-12.703,57.391-76.485c0-15.319,0-35.308,0-57.167 C809.141,880.759,806.282,893.462,751.75,893.462z" class="fill-primary"/></g></g><path fill="#31536E" d="M708.884,149.655c-28.163-28.162-73.823-28.162-101.985,0l-18.359,18.359l-18.358-18.358 c-28.163-28.163-73.824-28.163-101.986,0c-28.163,28.163-28.163,73.824,0,101.986l120.344,120.344l0,0l0.001,0.001l58.044-58.044 l43.943-43.942L690.525,270l18.358-18.359C737.047,223.479,737.047,177.818,708.884,149.655z" class="fill-primary"/><g id="stars_7" class="stars"><path fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4" d="M213.313,169.895c0-12.963-16.474-31.2-31.2-31.2c13.551,0,31.2-17.944,31.2-31.201c0,13.257,14.707,31.201,31.2,31.201 C227.727,138.695,213.313,156.932,213.313,169.895z"/><g><circle cx="932.273" cy="132.884" r="11.913" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="917.715" x2="898.994" y1="118.116" y2="99.396" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="947.667" x2="966.387" y1="148.068" y2="166.788" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="947.043" x2="965.763" y1="118.739" y2="100.02" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="917.715" x2="898.994" y1="148.068" y2="166.788" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="227.091" x2="204.003" y1="584.43" y2="607.52" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="195.892" x2="172.803" y1="615.631" y2="638.719" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="226.467" x2="203.379" y1="638.719" y2="615.631" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="195.268" x2="172.18" y1="607.52" y2="584.43" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><path fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4" d="M927.763,911.402c0,0-19.032,3.562-23.397,7.929c-4.366,4.367-7.928,23.396-7.928,23.396s-3.562-19.03-7.93-23.396 c-4.366-4.366-23.396-7.929-23.396-7.929s19.479-4.013,23.396-7.929s7.93-23.396,7.93-23.396s3.562,19.03,7.928,23.396 C908.73,907.841,927.763,911.402,927.763,911.402z"/><g><circle cx="917.977" cy="493.158" r="14.653" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="886.293" cy="493.158" r="5.676" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="917.977" cy="524.839" r="5.676" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="949.657" cy="493.158" r="5.676" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="917.977" cy="461.475" r="5.676" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="142.49" x2="190.941" y1="864.953" y2="913.405" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="190.941" x2="142.49" y1="864.953" y2="913.405" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="150" x2="127" y1="888.475" y2="888.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="185" x2="208" y1="888.475" y2="888.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="167" x2="167" y1="905.475" y2="929.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="167" x2="167" y1="872.475" y2="848.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g><g><line x1="127" x2="127" y1="328.475" y2="398.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><line x1="161" x2="92" y1="364.475" y2="364.475" fill="none" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="109.181" cy="380.935" r="6.212" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="109.181" cy="345.636" r="6.212" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="144.479" cy="380.935" r="6.212" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/><circle cx="144.479" cy="345.636" r="6.212" fill="#FFD92B" stroke="#31536E" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="10" stroke-width="4"/></g></g></g></svg>