decidim-challenges 0.5.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 (231) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE-AGPLv3.txt +661 -0
  3. data/README.md +49 -0
  4. data/Rakefile +9 -0
  5. data/app/cells/decidim/challenges/challenge_cell.rb +21 -0
  6. data/app/cells/decidim/challenges/challenge_g/show.erb +47 -0
  7. data/app/cells/decidim/challenges/challenge_g_cell.rb +69 -0
  8. data/app/cells/decidim/problems/problem_cell.rb +21 -0
  9. data/app/cells/decidim/problems/problem_g/show.erb +35 -0
  10. data/app/cells/decidim/problems/problem_g_cell.rb +61 -0
  11. data/app/cells/decidim/solutions/solution_cell.rb +21 -0
  12. data/app/cells/decidim/solutions/solution_g/show.erb +30 -0
  13. data/app/cells/decidim/solutions/solution_g_cell.rb +84 -0
  14. data/app/commands/decidim/challenges/admin/create_challenge.rb +67 -0
  15. data/app/commands/decidim/challenges/admin/destroy_challenge.rb +49 -0
  16. data/app/commands/decidim/challenges/admin/export_challenge_surveys.rb +45 -0
  17. data/app/commands/decidim/challenges/admin/publish_challenge.rb +40 -0
  18. data/app/commands/decidim/challenges/admin/unpublish_challenge.rb +40 -0
  19. data/app/commands/decidim/challenges/admin/update_challenge.rb +72 -0
  20. data/app/commands/decidim/challenges/admin/update_surveys.rb +43 -0
  21. data/app/commands/decidim/challenges/survey_challenge.rb +67 -0
  22. data/app/commands/decidim/command_utils.rb +20 -0
  23. data/app/commands/decidim/problems/admin/create_problem.rb +66 -0
  24. data/app/commands/decidim/problems/admin/destroy_problem.rb +49 -0
  25. data/app/commands/decidim/problems/admin/publish_problem.rb +40 -0
  26. data/app/commands/decidim/problems/admin/unpublish_problem.rb +40 -0
  27. data/app/commands/decidim/problems/admin/update_problem.rb +69 -0
  28. data/app/commands/decidim/solutions/admin/create_solution.rb +65 -0
  29. data/app/commands/decidim/solutions/admin/destroy_solution.rb +43 -0
  30. data/app/commands/decidim/solutions/admin/publish_solution.rb +40 -0
  31. data/app/commands/decidim/solutions/admin/unpublish_solution.rb +40 -0
  32. data/app/commands/decidim/solutions/admin/update_solution.rb +67 -0
  33. data/app/commands/decidim/solutions/create_solution.rb +67 -0
  34. data/app/controllers/concerns/decidim/challenges/admin/filterable.rb +27 -0
  35. data/app/controllers/concerns/decidim/challenges/orderable_challenges.rb +37 -0
  36. data/app/controllers/concerns/decidim/problems/admin/filterable.rb +27 -0
  37. data/app/controllers/concerns/decidim/problems/orderable_problems.rb +37 -0
  38. data/app/controllers/concerns/decidim/solutions/admin/filterable.rb +27 -0
  39. data/app/controllers/concerns/decidim/solutions/orderable_solutions.rb +37 -0
  40. data/app/controllers/concerns/decidim/with_default_filters.rb +23 -0
  41. data/app/controllers/concerns/decidim/with_sdgs.rb +19 -0
  42. data/app/controllers/decidim/challenges/admin/application_controller.rb +15 -0
  43. data/app/controllers/decidim/challenges/admin/challenge_publications_controller.rb +53 -0
  44. data/app/controllers/decidim/challenges/admin/challenges_controller.rb +108 -0
  45. data/app/controllers/decidim/challenges/admin/survey_form_controller.rb +43 -0
  46. data/app/controllers/decidim/challenges/admin/surveys_controller.rb +104 -0
  47. data/app/controllers/decidim/challenges/application_controller.rb +13 -0
  48. data/app/controllers/decidim/challenges/challenges_controller.rb +70 -0
  49. data/app/controllers/decidim/challenges/surveys_controller.rb +61 -0
  50. data/app/controllers/decidim/problems/admin/application_controller.rb +15 -0
  51. data/app/controllers/decidim/problems/admin/problem_publications_controller.rb +53 -0
  52. data/app/controllers/decidim/problems/admin/problems_controller.rb +102 -0
  53. data/app/controllers/decidim/problems/application_controller.rb +13 -0
  54. data/app/controllers/decidim/problems/problems_controller.rb +62 -0
  55. data/app/controllers/decidim/sdgs/admin/application_controller.rb +15 -0
  56. data/app/controllers/decidim/sdgs/admin/sdgs_controller.rb +18 -0
  57. data/app/controllers/decidim/sdgs/application_controller.rb +13 -0
  58. data/app/controllers/decidim/sdgs/sdgs_controller.rb +24 -0
  59. data/app/controllers/decidim/solutions/admin/application_controller.rb +15 -0
  60. data/app/controllers/decidim/solutions/admin/solution_publications_controller.rb +53 -0
  61. data/app/controllers/decidim/solutions/admin/solutions_controller.rb +106 -0
  62. data/app/controllers/decidim/solutions/application_controller.rb +13 -0
  63. data/app/controllers/decidim/solutions/solutions_controller.rb +115 -0
  64. data/app/forms/decidim/challenges/admin/challenge_surveys_form.rb +35 -0
  65. data/app/forms/decidim/challenges/admin/challenges_form.rb +78 -0
  66. data/app/forms/decidim/problems/admin/problems_form.rb +90 -0
  67. data/app/forms/decidim/solutions/admin/solutions_form.rb +71 -0
  68. data/app/forms/decidim/solutions/solutions_form.rb +50 -0
  69. data/app/helpers/decidim/challenges/application_helper.rb +25 -0
  70. data/app/helpers/decidim/challenges/challenge_cells_helper.rb +57 -0
  71. data/app/helpers/decidim/challenges/challenges_helper.rb +39 -0
  72. data/app/helpers/decidim/problems/application_helper.rb +10 -0
  73. data/app/helpers/decidim/problems/problem_cells_helper.rb +23 -0
  74. data/app/helpers/decidim/problems/problems_helper.rb +24 -0
  75. data/app/helpers/decidim/sdgs/sdgs_helper.rb +28 -0
  76. data/app/helpers/decidim/show_filters_helper.rb +13 -0
  77. data/app/helpers/decidim/solutions/application_helper.rb +27 -0
  78. data/app/helpers/decidim/solutions/solution_cells_helper.rb +56 -0
  79. data/app/helpers/decidim/solutions/solutions_helper.rb +21 -0
  80. data/app/models/decidim/application_record.rb +8 -0
  81. data/app/models/decidim/challenges/challenge.rb +82 -0
  82. data/app/models/decidim/challenges/survey.rb +19 -0
  83. data/app/models/decidim/problems/problem.rb +118 -0
  84. data/app/models/decidim/sdgs/sdg.rb +47 -0
  85. data/app/models/decidim/solutions/application_record.rb +10 -0
  86. data/app/models/decidim/solutions/solution.rb +69 -0
  87. data/app/packs/entrypoints/decidim_challenges.js +4 -0
  88. data/app/packs/entrypoints/decidim_challenges.scss +1 -0
  89. data/app/packs/entrypoints/decidim_problems.js +1 -0
  90. data/app/packs/entrypoints/decidim_problems.scss +1 -0
  91. data/app/packs/entrypoints/decidim_sdgs.js +6 -0
  92. data/app/packs/entrypoints/decidim_sdgs.scss +3 -0
  93. data/app/packs/entrypoints/decidim_shared.js +1 -0
  94. data/app/packs/entrypoints/decidim_shared.scss +1 -0
  95. data/app/packs/entrypoints/decidim_solutions.js +4 -0
  96. data/app/packs/entrypoints/decidim_solutions.scss +1 -0
  97. data/app/packs/fonts/Oswald-Medium.ttf +0 -0
  98. data/app/packs/images/decidim/challenges/decidim_challenges_icon.svg +1 -0
  99. data/app/packs/images/decidim/sdgs/ods-01.svg +11 -0
  100. data/app/packs/images/decidim/sdgs/ods-02.svg +11 -0
  101. data/app/packs/images/decidim/sdgs/ods-03.svg +11 -0
  102. data/app/packs/images/decidim/sdgs/ods-04.svg +12 -0
  103. data/app/packs/images/decidim/sdgs/ods-05.svg +12 -0
  104. data/app/packs/images/decidim/sdgs/ods-06.svg +20 -0
  105. data/app/packs/images/decidim/sdgs/ods-07.svg +18 -0
  106. data/app/packs/images/decidim/sdgs/ods-08.svg +13 -0
  107. data/app/packs/images/decidim/sdgs/ods-09.svg +25 -0
  108. data/app/packs/images/decidim/sdgs/ods-10.svg +13 -0
  109. data/app/packs/images/decidim/sdgs/ods-11.svg +41 -0
  110. data/app/packs/images/decidim/sdgs/ods-12.svg +11 -0
  111. data/app/packs/images/decidim/sdgs/ods-13.svg +57 -0
  112. data/app/packs/images/decidim/sdgs/ods-14.svg +14 -0
  113. data/app/packs/images/decidim/sdgs/ods-15.svg +11 -0
  114. data/app/packs/images/decidim/sdgs/ods-16.svg +14 -0
  115. data/app/packs/images/decidim/sdgs/ods-17.svg +39 -0
  116. data/app/packs/images/decidim/sdgs/sdg-wheel.png +0 -0
  117. data/app/packs/images/decidim/sdgs/un_emblem_square.png +0 -0
  118. data/app/packs/src/decidim/challenges/add_challenge.js +3 -0
  119. data/app/packs/src/decidim/challenges/admin/challenges_form.js +3 -0
  120. data/app/packs/src/decidim/sdgs/filter.js +75 -0
  121. data/app/packs/stylesheets/decidim/challenges/challenges.scss +3 -0
  122. data/app/packs/stylesheets/decidim/problems/problems.scss +3 -0
  123. data/app/packs/stylesheets/decidim/sdgs/ods.scss +185 -0
  124. data/app/packs/stylesheets/decidim/sdgs/sdgs_filter/button.scss +27 -0
  125. data/app/packs/stylesheets/decidim/sdgs/sdgs_filter/modal.scss +60 -0
  126. data/app/packs/stylesheets/decidim/shared/_cards.scss +52 -0
  127. data/app/packs/stylesheets/decidim/shared/base.scss +9 -0
  128. data/app/packs/stylesheets/decidim/solutions/solutions.scss +3 -0
  129. data/app/permissions/decidim/challenges/admin/permissions.rb +88 -0
  130. data/app/permissions/decidim/challenges/permissions.rb +27 -0
  131. data/app/permissions/decidim/problems/admin/permissions.rb +52 -0
  132. data/app/permissions/decidim/problems/permissions.rb +16 -0
  133. data/app/permissions/decidim/solutions/admin/permissions.rb +58 -0
  134. data/app/permissions/decidim/solutions/permissions.rb +17 -0
  135. data/app/presenters/decidim/challenges/challenge_presenter.rb +134 -0
  136. data/app/presenters/decidim/problems/problem_presenter.rb +108 -0
  137. data/app/presenters/decidim/solutions/solution_presenter.rb +198 -0
  138. data/app/serializers/decidim/challenges/data_serializer.rb +46 -0
  139. data/app/serializers/decidim/challenges/survey_serializer.rb +37 -0
  140. data/app/types/decidim/challenges/challenge_type.rb +28 -0
  141. data/app/types/decidim/challenges/challenges_type.rb +32 -0
  142. data/app/types/decidim/problems/problem_type.rb +29 -0
  143. data/app/types/decidim/problems/problems_type.rb +32 -0
  144. data/app/types/decidim/solutions/solution_type.rb +25 -0
  145. data/app/types/decidim/solutions/solutions_type.rb +32 -0
  146. data/app/views/decidim/challenges/admin/challenges/_form.html.erb +78 -0
  147. data/app/views/decidim/challenges/admin/challenges/edit.html.erb +24 -0
  148. data/app/views/decidim/challenges/admin/challenges/index.html.erb +88 -0
  149. data/app/views/decidim/challenges/admin/challenges/new.html.erb +18 -0
  150. data/app/views/decidim/challenges/admin/surveys/_form.html.erb +9 -0
  151. data/app/views/decidim/challenges/admin/surveys/edit.html.erb +39 -0
  152. data/app/views/decidim/challenges/admin/surveys/index.html.erb +49 -0
  153. data/app/views/decidim/challenges/admin/surveys/show.html.erb +43 -0
  154. data/app/views/decidim/challenges/challenges/_challenge.html.erb +1 -0
  155. data/app/views/decidim/challenges/challenges/_challenges.html.erb +11 -0
  156. data/app/views/decidim/challenges/challenges/_related_problems.html.erb +14 -0
  157. data/app/views/decidim/challenges/challenges/_sidebar_data.html.erb +60 -0
  158. data/app/views/decidim/challenges/challenges/index.html.erb +29 -0
  159. data/app/views/decidim/challenges/challenges/index.js.erb +5 -0
  160. data/app/views/decidim/challenges/challenges/show.html.erb +41 -0
  161. data/app/views/decidim/problems/admin/problems/_form.html.erb +79 -0
  162. data/app/views/decidim/problems/admin/problems/edit.html.erb +24 -0
  163. data/app/views/decidim/problems/admin/problems/index.html.erb +93 -0
  164. data/app/views/decidim/problems/admin/problems/new.html.erb +18 -0
  165. data/app/views/decidim/problems/problems/_problem.html.erb +1 -0
  166. data/app/views/decidim/problems/problems/_problems.html.erb +11 -0
  167. data/app/views/decidim/problems/problems/_sidebar_data.html.erb +70 -0
  168. data/app/views/decidim/problems/problems/index.html.erb +28 -0
  169. data/app/views/decidim/problems/problems/index.js.erb +5 -0
  170. data/app/views/decidim/problems/problems/show.html.erb +38 -0
  171. data/app/views/decidim/sdgs/sdgs/_objectives.html.erb +320 -0
  172. data/app/views/decidim/sdgs/sdgs/_ods.html.erb +132 -0
  173. data/app/views/decidim/sdgs/sdgs/index.html.erb +64 -0
  174. data/app/views/decidim/sdgs/sdgs_filter/_filter_selector.html.erb +7 -0
  175. data/app/views/decidim/sdgs/sdgs_filter/_modal.html.erb +35 -0
  176. data/app/views/decidim/shared/_related_solutions.html.erb +14 -0
  177. data/app/views/decidim/solutions/admin/solutions/_documents.html.erb +13 -0
  178. data/app/views/decidim/solutions/admin/solutions/_form.html.erb +70 -0
  179. data/app/views/decidim/solutions/admin/solutions/_photos.html.erb +13 -0
  180. data/app/views/decidim/solutions/admin/solutions/edit.html.erb +24 -0
  181. data/app/views/decidim/solutions/admin/solutions/index.html.erb +97 -0
  182. data/app/views/decidim/solutions/admin/solutions/new.html.erb +18 -0
  183. data/app/views/decidim/solutions/admin/solutions/show.html.erb +114 -0
  184. data/app/views/decidim/solutions/solutions/_form.html.erb +22 -0
  185. data/app/views/decidim/solutions/solutions/_sidebar_data.html.erb +114 -0
  186. data/app/views/decidim/solutions/solutions/_solution.html.erb +1 -0
  187. data/app/views/decidim/solutions/solutions/_solutions.html.erb +13 -0
  188. data/app/views/decidim/solutions/solutions/index.html.erb +37 -0
  189. data/app/views/decidim/solutions/solutions/index.js.erb +5 -0
  190. data/app/views/decidim/solutions/solutions/new.html.erb +20 -0
  191. data/app/views/decidim/solutions/solutions/show.html.erb +72 -0
  192. data/config/assets.rb +27 -0
  193. data/config/i18n-tasks.yml +10 -0
  194. data/config/locales/ca.yml +1244 -0
  195. data/config/locales/cs.yml +668 -0
  196. data/config/locales/en.yml +1245 -0
  197. data/config/locales/es.yml +1250 -0
  198. data/config/locales/oc.yml +1229 -0
  199. data/db/migrate/20201014125000_create_decidim_challenges_challenges.rb +23 -0
  200. data/db/migrate/20201103155100_create_decidim_problems_problems.rb +25 -0
  201. data/db/migrate/20201116111200_create_decidim_solutions_solutions.rb +21 -0
  202. data/db/migrate/20210413083244_create_decidim_challenges_surveys.rb +14 -0
  203. data/db/migrate/20210413083507_add_survey_attributes_to_challenges.rb +7 -0
  204. data/db/migrate/20210413083604_add_questionnaire_to_existing_challenges.rb +15 -0
  205. data/db/migrate/20210413112229_add_challenge_reference_to_solutions.rb +7 -0
  206. data/db/migrate/20210427091033_remove_require_null_in_problems_for_solutions.rb +7 -0
  207. data/db/migrate/20220407110503_add_card_image_to_challenges.rb +7 -0
  208. data/db/migrate/20240919094714_add_public_fields_to_solutions.rb +10 -0
  209. data/lib/decidim/challenges/admin.rb +10 -0
  210. data/lib/decidim/challenges/admin_engine.rb +37 -0
  211. data/lib/decidim/challenges/component.rb +65 -0
  212. data/lib/decidim/challenges/engine.rb +39 -0
  213. data/lib/decidim/challenges/test/factories.rb +59 -0
  214. data/lib/decidim/challenges/version.rb +14 -0
  215. data/lib/decidim/challenges.rb +13 -0
  216. data/lib/decidim/problems/admin.rb +10 -0
  217. data/lib/decidim/problems/admin_engine.rb +25 -0
  218. data/lib/decidim/problems/component.rb +51 -0
  219. data/lib/decidim/problems/engine.rb +31 -0
  220. data/lib/decidim/problems/test/factories.rb +39 -0
  221. data/lib/decidim/sdgs/admin.rb +10 -0
  222. data/lib/decidim/sdgs/admin_engine.rb +28 -0
  223. data/lib/decidim/sdgs/component.rb +44 -0
  224. data/lib/decidim/sdgs/engine.rb +23 -0
  225. data/lib/decidim/sdgs/test/factories.rb +13 -0
  226. data/lib/decidim/solutions/admin.rb +10 -0
  227. data/lib/decidim/solutions/admin_engine.rb +25 -0
  228. data/lib/decidim/solutions/component.rb +52 -0
  229. data/lib/decidim/solutions/engine.rb +31 -0
  230. data/lib/decidim/solutions/test/factories.rb +28 -0
  231. metadata +316 -0
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Problems
5
+ # Custom helpers, scoped to the problems engine.
6
+ #
7
+ module ApplicationHelper
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Problems
5
+ # Custom helpers, scoped to the problems engine.
6
+ #
7
+ module ProblemCellsHelper
8
+ include Decidim::Problems::ApplicationHelper
9
+ include Decidim::Problems::Engine.routes.url_helpers
10
+ include Decidim::LayoutHelper
11
+ include Decidim::ApplicationHelper
12
+ include Decidim::TranslationsHelper
13
+ include Decidim::ResourceReferenceHelper
14
+ include Decidim::TranslatableAttributes
15
+ include Decidim::CardHelper
16
+ include WithSdgs
17
+
18
+ def current_component
19
+ model.component
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Problems
5
+ # Custom helpers, scoped to the problems engine.
6
+ #
7
+ module ProblemsHelper
8
+ def filter_sections
9
+ items = []
10
+ items.append(method: :with_any_state, collection: filter_custom_state_values, label_scope: "decidim.problems.problems.filters", id: "state")
11
+ items.append(method: :related_to, collection: linked_classes_filter_values_for(Decidim::Challenges::Challenge), label_scope: "decidim.problems.problems.filters",
12
+ id: "related_to", type: :radio_buttons)
13
+
14
+ if current_participatory_space.has_subscopes?
15
+ items.append(method: :with_any_sectorial_scope, collection: filter_global_scopes_values, label_scope: "decidim.problems.problems.filters", id: "sectorial_scope")
16
+ items.append(method: :with_any_technological_scope, collection: filter_global_scopes_values, label_scope: "decidim.problems.problems.filters", id: "technological_scope")
17
+ items.append(method: :with_any_territorial_scope, collection: filter_global_scopes_values, label_scope: "decidim.problems.problems.filters", id: "territorial_scope")
18
+ end
19
+
20
+ items.reject { |item| item[:collection].blank? }
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Sdgs
5
+ # Custom helpers, scoped to the Sdgs engine.
6
+ #
7
+ module SdgsHelper
8
+ def sdgs_filter_selector(form)
9
+ render partial: "decidim/sdgs/sdgs_filter/filter_selector", locals: { form: }
10
+ end
11
+
12
+ def t_sdg(code)
13
+ return if code.blank?
14
+
15
+ t(code, scope: "decidim.sdgs.names")
16
+ end
17
+
18
+ def filter_sdgs_values
19
+ Decidim::CheckBoxesTreeHelper::TreeNode.new(
20
+ Decidim::CheckBoxesTreeHelper::TreePoint.new("", t("decidim.challenges.challenges_helper.filter_state_values.all")),
21
+ Decidim::Sdgs::Sdg::SDGS.map do |sdg_code|
22
+ Decidim::CheckBoxesTreeHelper::TreePoint.new(sdg_code, I18n.t("#{sdg_code}.objectives.subtitle", scope: "decidim.components.sdgs"))
23
+ end
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module ShowFiltersHelper
5
+ def css_full_cardgrid_cols(hide_filters)
6
+ if hide_filters
7
+ "row small-up-1 medium-up-3 card-grid"
8
+ else
9
+ "row small-up-1 medium-up-2 card-grid"
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Solutions
5
+ # Custom helpers, scoped to the solutions engine.
6
+ #
7
+ module ApplicationHelper
8
+ include Decidim::RichTextEditorHelper
9
+
10
+ def text_editor_for_description(form)
11
+ options = {
12
+ class: "js-hashtags",
13
+ hashtaggable: true,
14
+ value: form_presenter.description(extras: false).strip,
15
+ }
16
+
17
+ text_editor_for(form, :description, options)
18
+ end
19
+
20
+ def participatory_space_challenges
21
+ challenge_component = current_participatory_space.components.find_by(manifest_name: "challenges")
22
+
23
+ ::Decidim::Challenges::Challenge.where(decidim_component_id: challenge_component.id)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Solutions
5
+ # Custom helpers, scoped to the solutions engine.
6
+ #
7
+ module SolutionCellsHelper
8
+ include Decidim::Solutions::ApplicationHelper
9
+ include Decidim::Solutions::Engine.routes.url_helpers
10
+ include Decidim::LayoutHelper
11
+ include Decidim::ApplicationHelper
12
+ include Decidim::TranslationsHelper
13
+ include Decidim::ResourceReferenceHelper
14
+ include Decidim::TranslatableAttributes
15
+ include Decidim::CardHelper
16
+
17
+ delegate :title, :state, :published_state?, :withdrawn?, :amendable?, :emendation?, to: :model
18
+
19
+ def has_actions?
20
+ return context[:has_actions] if context[:has_actions].present?
21
+
22
+ solutions_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
23
+ end
24
+
25
+ def has_footer?
26
+ return context[:has_footer] if context[:has_footer].present?
27
+
28
+ solutions_controller? && index_action? && current_settings.votes_enabled? && !model.draft?
29
+ end
30
+
31
+ def solutions_controller?
32
+ context[:controller].instance_of?(::Decidim::Solutions::SolutionsController)
33
+ end
34
+
35
+ def index_action?
36
+ context[:controller].action_name == "index"
37
+ end
38
+
39
+ def current_settings
40
+ model.component.current_settings
41
+ end
42
+
43
+ def component_settings
44
+ model.component.settings
45
+ end
46
+
47
+ def current_component
48
+ model.component
49
+ end
50
+
51
+ def from_context
52
+ options[:from]
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Solutions
5
+ # Custom helpers, scoped to the challenges engine.
6
+ #
7
+ module SolutionsHelper
8
+ def filter_sections
9
+ items = []
10
+ if current_participatory_space.has_subscopes?
11
+ items.append(method: :with_any_territorial_scope, collection: filter_global_scopes_values, label_scope: "decidim.problems.problems.filters",
12
+ id: "territorial_scope")
13
+ end
14
+ items.append(method: :related_to, collection: linked_classes_filter_values_for(Decidim::Challenges::Challenge), label_scope: "decidim.solutions.solutions.filters",
15
+ id: "related_to", type: :radio_buttons)
16
+
17
+ items.reject { |item| item[:collection].blank? }
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ # Abstract class from which all models in this engine inherit.
5
+ class ApplicationRecord < ActiveRecord::Base
6
+ self.abstract_class = true
7
+ end
8
+ end
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Challenges
5
+ # The data store for a Challenge in the Decidim::Challenges component.
6
+ class Challenge < Decidim::ApplicationRecord
7
+ include Decidim::HasComponent
8
+ include Decidim::FilterableResource
9
+ include Decidim::ScopableResource
10
+ include Decidim::Loggable
11
+ include Decidim::Publicable
12
+ include Decidim::Resourceable
13
+ include Decidim::Searchable
14
+ include Decidim::Traceable
15
+ include Decidim::TranslatableAttributes
16
+ include Decidim::Forms::HasQuestionnaire
17
+ include Decidim::Randomable
18
+ include Decidim::HasUploadValidations
19
+
20
+ belongs_to :scope,
21
+ foreign_key: "decidim_scope_id",
22
+ class_name: "Decidim::Scope",
23
+ optional: true
24
+
25
+ has_many :surveys, class_name: "Decidim::Challenges::Survey", foreign_key: "decidim_challenge_id", dependent: :destroy
26
+
27
+ VALID_STATES = [:proposal, :execution, :finished].freeze
28
+ enum state: VALID_STATES
29
+
30
+ has_many :problems,
31
+ class_name: "Decidim::Problems::Problem",
32
+ foreign_key: "decidim_challenges_challenge_id", dependent: :restrict_with_exception
33
+ has_many :solutions,
34
+ class_name: "Decidim::Solutions::Solution",
35
+ foreign_key: "decidim_challenges_challenge_id", dependent: :restrict_with_exception
36
+
37
+ component_manifest_name "challenges"
38
+
39
+ has_one_attached :card_image
40
+ validates_upload :card_image, uploader: Decidim::ImageUploader
41
+
42
+ scope :published, -> { where.not(published_at: nil) }
43
+ scope :in_proposal, -> { where(state: VALID_STATES.index(:proposal)) }
44
+ scope :in_execution, -> { where(state: VALID_STATES.index(:execution)) }
45
+ scope :in_finished, -> { where(state: VALID_STATES.index(:finished)) }
46
+
47
+ scope :with_any_state, lambda { |*values|
48
+ where(state: Array(values).map(&:to_sym) & VALID_STATES)
49
+ }
50
+
51
+ scope :search_text_cont, lambda { |search_text|
52
+ where("title ->> '#{I18n.locale}' ILIKE ?", "%#{search_text}%")
53
+ }
54
+
55
+ scope :with_any_sdgs_codes, lambda { |*values|
56
+ where(sdg_code: Array(values).map(&:to_sym))
57
+ }
58
+
59
+ def self.ransackable_scopes(_auth_object = nil)
60
+ [:with_any_state, :search_text_cont, :with_any_sdgs_codes, :with_any_scope, :related_to]
61
+ end
62
+
63
+ searchable_fields({
64
+ scope_id: :decidim_scope_id,
65
+ participatory_space: :itself,
66
+ A: :title,
67
+ B: :local_description,
68
+ C: :global_description,
69
+ D: "",
70
+ datetime: :published_at,
71
+ },
72
+ index_on_create: ->(challenge) { challenge.published? && challenge.visible? },
73
+ index_on_update: ->(challenge) { challenge.published? && challenge.visible? })
74
+
75
+ def published?
76
+ published_at.present?
77
+ end
78
+
79
+ def remove_card_image; end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Challenges
5
+ # The data store for a Survey in the Decidim::Challenges component.
6
+ class Survey < Decidim::ApplicationRecord
7
+ include Decidim::DownloadYourData
8
+
9
+ belongs_to :challenge, foreign_key: "decidim_challenge_id", class_name: "Decidim::Challenges::Challenge"
10
+ belongs_to :user, foreign_key: "decidim_user_id", class_name: "Decidim::User"
11
+
12
+ validates :user, uniqueness: { scope: :challenge }
13
+
14
+ def self.export_serializer
15
+ Decidim::Challenges::DownloadYourDataSurveySerializer
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,118 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Problems
5
+ # The data store for a Problem in the Decidim::Problems component.
6
+ class Problem < Decidim::ApplicationRecord
7
+ include Decidim::HasComponent
8
+ include Decidim::FilterableResource
9
+ include Decidim::ScopableResource
10
+ include Decidim::Loggable
11
+ include Decidim::Publicable
12
+ include Decidim::Resourceable
13
+ include Decidim::Searchable
14
+ include Decidim::Traceable
15
+ include Decidim::TranslatableAttributes
16
+ include Decidim::Randomable
17
+
18
+ VALID_STATES = [:proposal, :execution, :finished].freeze
19
+ enum state: VALID_STATES
20
+
21
+ component_manifest_name "problems"
22
+
23
+ belongs_to :challenge, foreign_key: "decidim_challenges_challenge_id", class_name: "Decidim::Challenges::Challenge"
24
+
25
+ belongs_to :sectorial_scope,
26
+ foreign_key: "decidim_sectorial_scope_id",
27
+ class_name: "Decidim::Scope",
28
+ optional: true
29
+ belongs_to :technological_scope,
30
+ foreign_key: "decidim_technological_scope_id",
31
+ class_name: "Decidim::Scope",
32
+ optional: true
33
+ has_many :solutions,
34
+ class_name: "Decidim::Solutions::Solution",
35
+ foreign_key: "decidim_problems_problem_id", dependent: :restrict_with_exception
36
+
37
+ scope :published, -> { where.not(published_at: nil) }
38
+ scope :in_proposal, -> { where(state: VALID_STATES.index(:proposal)) }
39
+ scope :in_execution, -> { where(state: VALID_STATES.index(:execution)) }
40
+ scope :in_finished, -> { where(state: VALID_STATES.index(:finished)) }
41
+
42
+ scope :with_any_state, lambda { |*values|
43
+ where(state: Array(values).map(&:to_sym) & VALID_STATES)
44
+ }
45
+
46
+ scope :search_text_cont, lambda { |search_text|
47
+ where("title ->> '#{I18n.locale}' ILIKE ?", "%#{search_text}%")
48
+ }
49
+
50
+ scope :with_any_sdgs_codes, lambda { |*values|
51
+ joins(:challenge).where("decidim_challenges_challenges" => { sdg_code: Array(values).map(&:to_sym) })
52
+ }
53
+
54
+ scope :with_any_sectorial_scope, lambda { |*sectorial_scope_id|
55
+ if sectorial_scope_id.include?("all")
56
+ all
57
+ else
58
+ clean_scope_ids = sectorial_scope_id
59
+
60
+ conditions = []
61
+ conditions << "#{model_name.plural}.decidim_sectorial_scope_id IS NULL" if clean_scope_ids.delete("global")
62
+ conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?
63
+
64
+ includes(:sectorial_scope).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
65
+ end
66
+ }
67
+
68
+ scope :with_any_technological_scope, lambda { |*technological_scope_id|
69
+ if technological_scope_id.include?("all")
70
+ all
71
+ else
72
+ clean_scope_ids = technological_scope_id
73
+
74
+ conditions = []
75
+ conditions << "#{model_name.plural}.decidim_technological_scope_id IS NULL" if clean_scope_ids.delete("global")
76
+ conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?
77
+
78
+ includes(:technological_scope).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
79
+ end
80
+ }
81
+
82
+ scope :with_any_territorial_scope, lambda { |*territorial_scope_id|
83
+ if territorial_scope_id.include?("all")
84
+ all
85
+ else
86
+ clean_scope_ids = territorial_scope_id
87
+
88
+ conditions = []
89
+ conditions << "decidim_challenges_challenges.decidim_scope_id IS NULL" if clean_scope_ids.delete("global")
90
+ conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?
91
+
92
+ includes(challenge: :scope).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
93
+ end
94
+ }
95
+
96
+ def self.ransackable_scopes(_auth_object = nil)
97
+ [:with_any_state, :search_text_cont, :with_any_sdgs_codes,
98
+ :with_any_sectorial_scope, :with_any_technological_scope, :with_any_territorial_scope, :related_to]
99
+ end
100
+
101
+ searchable_fields({
102
+ scope_id: "decidim_sectorial_scope_id",
103
+ participatory_space: :itself,
104
+ A: :title,
105
+ B: :description,
106
+ C: "",
107
+ D: "",
108
+ datetime: :published_at,
109
+ },
110
+ index_on_create: ->(problem) { problem.published? && problem.visible? },
111
+ index_on_update: ->(problem) { problem.published? && problem.visible? })
112
+
113
+ def published?
114
+ published_at.present?
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Sdgs
5
+ # A Sustainable Development Goal
6
+ class Sdg
7
+ SDGS = [
8
+ :no_poverty,
9
+ :zero_hunger,
10
+ :good_health,
11
+ :quality_education,
12
+ :gender_equality,
13
+ :clean_water,
14
+ :clean_energy,
15
+ :decent_work,
16
+ :iiai,
17
+ :reduced_inequalities,
18
+ :sustainable_cities,
19
+ :responsible_consumption,
20
+ :climate_action,
21
+ :life_below_water,
22
+ :life_on_land,
23
+ :pjsi,
24
+ :partnership,
25
+ ].freeze
26
+ # Parameter
27
+ # idxs - Array of Sdgs indexes, between 1 and 17
28
+ def self.codes_from_idxs(idxs)
29
+ idxs.collect do |idx|
30
+ code_from_idx(idx)
31
+ end
32
+ end
33
+
34
+ # Parameter
35
+ # idx - The index of the Sdg, between 1 and 17
36
+ def self.code_from_idx(idx)
37
+ SDGS[idx.to_i - 1]
38
+ end
39
+
40
+ # Parameter
41
+ # sdg - the sdg
42
+ def self.index_from_code(code)
43
+ SDGS.index(code)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Solutions
5
+ # Abstract class from which all models in this engine inherit.
6
+ class ApplicationRecord < ActiveRecord::Base
7
+ self.abstract_class = true
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Decidim
4
+ module Solutions
5
+ # The data store for a Solution in the Decidim::Solutions component.
6
+ class Solution < Solutions::ApplicationRecord
7
+ include Decidim::HasComponent
8
+ include Decidim::FilterableResource
9
+ include Decidim::Loggable
10
+ include Decidim::Publicable
11
+ include Decidim::Resourceable
12
+ include Decidim::Searchable
13
+ include Decidim::Traceable
14
+ include Decidim::TranslatableAttributes
15
+ include Decidim::Randomable
16
+ include Decidim::HasAttachments
17
+ include Decidim::Publicable
18
+
19
+ component_manifest_name "solutions"
20
+
21
+ belongs_to :problem, foreign_key: "decidim_problems_problem_id", class_name: "Decidim::Problems::Problem", optional: true
22
+ belongs_to :challenge, foreign_key: "decidim_challenges_challenge_id", class_name: "Decidim::Challenges::Challenge", optional: true
23
+ belongs_to :author, class_name: "Decidim::User"
24
+
25
+ scope :published, -> { where.not(published_at: nil) }
26
+
27
+ scope :search_text_cont, lambda { |search_text|
28
+ where("title ->> '#{I18n.locale}' ILIKE ?", "%#{search_text}%")
29
+ }
30
+
31
+ scope :with_any_sdgs_codes, lambda { |*values|
32
+ joins(:challenge).where("decidim_challenges_challenges" => { sdg_code: Array(values).map(&:to_sym) })
33
+ }
34
+
35
+ scope :with_any_territorial_scope, lambda { |*territorial_scope_id|
36
+ if territorial_scope_id.include?("all")
37
+ all
38
+ else
39
+ clean_scope_ids = territorial_scope_id
40
+
41
+ conditions = []
42
+ conditions << "decidim_challenges_challenges.decidim_scope_id IS NULL" if clean_scope_ids.delete("global")
43
+ conditions.concat(["? = ANY(decidim_scopes.part_of)"] * clean_scope_ids.count) if clean_scope_ids.any?
44
+
45
+ includes(problem: { challenge: :scope }).references(:decidim_scopes).where(conditions.join(" OR "), *clean_scope_ids.map(&:to_i))
46
+ end
47
+ }
48
+
49
+ def self.ransackable_scopes(_auth_object = nil)
50
+ [:search_text_cont, :with_any_territorial_scope, :with_any_sdgs_codes, :related_to]
51
+ end
52
+
53
+ searchable_fields({
54
+ participatory_space: :itself,
55
+ A: :title,
56
+ B: :description,
57
+ C: "",
58
+ D: "",
59
+ datetime: :published_at,
60
+ },
61
+ index_on_create: ->(solution) { solution.published? && solution.visible? },
62
+ index_on_update: ->(solution) { solution.published? && solution.visible? })
63
+
64
+ def published?
65
+ published_at.present?
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,4 @@
1
+ // Images
2
+ require.context("../images", true)
3
+
4
+ import "entrypoints/decidim_challenges.scss";
@@ -0,0 +1 @@
1
+ @import "stylesheets/decidim/challenges/challenges";
@@ -0,0 +1 @@
1
+ import "entrypoints/decidim_problems.scss";
@@ -0,0 +1 @@
1
+ @import "stylesheets/decidim/problems/problems";
@@ -0,0 +1,6 @@
1
+ // Images
2
+ require.context("../images", true)
3
+
4
+ import "entrypoints/decidim_sdgs.scss";
5
+
6
+ import "src/decidim/sdgs/filter.js";
@@ -0,0 +1,3 @@
1
+ @import "stylesheets/decidim/sdgs/sdgs_filter/button.scss";
2
+ @import "stylesheets/decidim/sdgs/sdgs_filter/modal.scss";
3
+ @import "stylesheets/decidim/sdgs/ods.scss";
@@ -0,0 +1 @@
1
+ import "entrypoints/decidim_shared.scss";
@@ -0,0 +1 @@
1
+ @import "stylesheets/decidim/shared/base";
@@ -0,0 +1,4 @@
1
+ // Images
2
+ require.context("../images", true)
3
+
4
+ import "entrypoints/decidim_solutions.scss";
@@ -0,0 +1 @@
1
+ @import "stylesheets/decidim/solutions/solutions";
Binary file
@@ -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,11 @@
1
+ <?xml version="1.0" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
3
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
4
+ <svg version="1.0" xmlns="http://www.w3.org/2000/svg"
5
+ width="1200.000000pt" height="1200.000000pt" viewBox="0 0 1200.000000 1200.000000"
6
+ preserveAspectRatio="xMidYMid meet">
7
+ <g transform="translate(0.000000,1200.000000) scale(0.100000,-0.100000)"
8
+ fill="#e5243b" stroke="none">
9
+ <path d="M 0 6000 L 0 0 L 6000 0 L 12000 0 L 12000 6000 L 12000 12000 L 6000 12000 L 0 12000 L 0 6000 Z M 1488 9823 L 1490 8670 L 1270 8670 L 1050 8670 L 1050 9590 C 1050 10096 1048 10510 1046 10510 C 1044 10510 1025 10503 1005 10494 C 984 10486 911 10459 843 10435 L 720 10391 L 720 10560 C 720 10679 723 10730 731 10730 C 748 10730 951 10834 1018 10876 C 1049 10896 1092 10928 1113 10947 L 1151 10980 L 1318 10978 L 1485 10975 L 1488 9823 Z M 2288 6605 C 2502 6556 2613 6315 2510 6121 C 2472 6051 2432 6012 2357 5973 C 2312 5949 2293 5945 2215 5945 C 2138 5945 2117 5949 2068 5972 C 1781 6106 1825 6531 2134 6606 C 2202 6622 2210 6622 2288 6605 Z M 9662 6609 C 9788 6582 9884 6498 9920 6383 C 9944 6306 9945 6251 9925 6184 C 9843 5906 9476 5852 9317 6096 C 9191 6289 9298 6551 9524 6606 C 9590 6622 9599 6622 9662 6609 Z M 5177 6398 C 5255 6369 5329 6295 5359 6215 C 5403 6099 5374 5964 5288 5878 C 5220 5809 5161 5785 5060 5785 C 4960 5785 4900 5809 4835 5875 C 4769 5940 4746 6000 4745 6100 C 4745 6173 4749 6193 4773 6242 C 4846 6390 5020 6457 5177 6398 Z M 7074 6400 C 7146 6373 7211 6314 7246 6243 C 7271 6193 7275 6174 7274 6100 C 7274 6030 7270 6007 7251 5970 C 7216 5904 7192 5875 7146 5842 C 7020 5753 6853 5763 6741 5868 C 6668 5937 6645 5994 6645 6105 C 6645 6186 6648 6201 6675 6249 C 6754 6392 6923 6456 7074 6400 Z M 2652 5809 C 2815 5775 2954 5644 2995 5485 C 3007 5436 3010 5347 3010 4958 C 3010 4524 3013 4465 3035 4500 C 3038 4506 3060 4510 3084 4510 C 3136 4510 3165 4482 3238 4360 C 3314 4233 3348 4190 3385 4174 C 3433 4154 3727 4154 3775 4174 C 3812 4190 3854 4243 3926 4365 C 3993 4479 4024 4510 4073 4510 C 4094 4510 4120 4505 4131 4500 C 4145 4492 4150 4493 4150 4502 C 4150 4534 4423 5398 4447 5443 C 4482 5508 4556 5581 4612 5609 C 4655 5629 4668 5630 5061 5630 C 5438 5630 5468 5628 5507 5610 C 5562 5586 5637 5509 5673 5444 C 5712 5369 5970 4527 5971 4468 C 5972 4409 5954 4372 5910 4342 C 5844 4298 5754 4325 5715 4400 C 5709 4414 5679 4506 5651 4605 C 5622 4704 5595 4796 5590 4810 C 5585 4824 5567 4885 5550 4945 C 5484 5172 5475 5195 5452 5198 C 5439 5200 5427 5194 5420 5181 C 5408 5158 5410 5151 5495 4845 C 5521 4752 5546 4662 5550 4645 C 5554 4629 5576 4548 5599 4465 C 5642 4312 5712 4056 5756 3896 C 5770 3846 5778 3800 5776 3793 C 5772 3783 5732 3780 5605 3780 L 5440 3780 L 5440 3283 L 5440 2787 L 5415 2743 C 5344 2623 5179 2635 5119 2765 C 5102 2802 5100 2840 5100 3293 L 5100 3780 L 5060 3780 L 5020 3780 L 5020 3296 C 5020 2962 5016 2802 5009 2779 C 4961 2638 4772 2619 4703 2749 L 4680 2793 L 4680 3287 L 4680 3780 L 4515 3780 C 4383 3780 4348 3783 4344 3794 C 4341 3802 4354 3863 4374 3931 C 4393 3999 4429 4129 4454 4220 C 4479 4311 4540 4531 4589 4710 C 4715 5168 4712 5157 4700 5180 C 4686 5206 4664 5205 4646 5178 C 4638 5165 4584 4991 4525 4790 C 4466 4589 4412 4414 4405 4400 C 4384 4360 4346 4330 4307 4323 C 4260 4316 4228 4324 4192 4355 C 4162 4380 4161 4380 4155 4359 C 4151 4348 4089 4232 4017 4102 C 3853 3806 3857 3834 3935 3545 C 3966 3430 3998 3315 4006 3291 C 4031 3212 4029 3210 3950 3210 L 3880 3210 L 3880 2983 C 3880 2733 3877 2721 3821 2683 C 3760 2642 3676 2661 3633 2727 C 3617 2751 3615 2783 3612 2982 L 3609 3210 L 3580 3210 L 3551 3210 L 3548 2982 C 3545 2783 3543 2751 3527 2727 C 3486 2663 3404 2643 3343 2680 C 3284 2716 3280 2735 3280 2985 L 3280 3210 L 3210 3210 C 3172 3210 3140 3214 3140 3220 C 3140 3225 3170 3338 3207 3472 C 3263 3671 3275 3728 3275 3790 L 3275 3865 L 3135 4117 L 2995 4369 L 2969 4344 C 2908 4285 2798 4306 2760 4384 C 2741 4425 2740 4444 2740 4851 C 2740 5168 2737 5279 2728 5288 C 2712 5304 2663 5303 2653 5288 C 2649 5281 2643 4714 2640 4028 L 2635 2782 L 2604 2743 C 2560 2689 2516 2666 2455 2666 C 2389 2666 2333 2695 2295 2749 L 2265 2792 L 2260 3523 C 2257 3926 2251 4261 2247 4268 C 2242 4274 2226 4280 2210 4280 C 2194 4280 2178 4274 2173 4268 C 2169 4261 2163 3924 2160 3518 L 2155 2782 L 2124 2743 C 2080 2689 2036 2666 1975 2666 C 1909 2666 1853 2695 1815 2749 L 1785 2792 L 1780 4033 C 1777 4716 1771 5281 1767 5288 C 1757 5303 1708 5304 1692 5288 C 1683 5279 1680 5167 1680 4848 C 1680 4384 1678 4369 1626 4335 C 1612 4325 1600 4310 1600 4300 C 1600 4290 1571 4127 1535 3938 C 1499 3749 1461 3548 1450 3490 C 1340 2901 1298 2694 1283 2678 C 1261 2654 1205 2655 1180 2680 C 1154 2706 1155 2728 1185 2885 C 1224 3091 1358 3801 1386 3950 C 1416 4112 1449 4288 1455 4314 C 1457 4325 1449 4347 1437 4364 C 1415 4395 1415 4398 1412 4900 C 1410 5227 1413 5422 1420 5455 C 1455 5625 1583 5759 1753 5805 C 1820 5823 2569 5826 2652 5809 Z M 10042 5809 C 10208 5774 10351 5634 10389 5469 C 10395 5442 10400 5223 10400 4915 C 10400 4427 10399 4404 10380 4373 C 10344 4313 10259 4292 10199 4327 C 10183 4337 10161 4363 10150 4385 C 10131 4424 10130 4448 10130 4851 C 10130 5168 10127 5279 10118 5288 C 10099 5307 10052 5303 10040 5281 C 10033 5268 10030 4861 10030 4035 C 10030 2838 10030 2808 10010 2771 C 9985 2720 9943 2686 9886 2670 C 9800 2646 9707 2691 9669 2775 C 9652 2813 9650 2858 9650 3535 C 9650 4082 9647 4259 9638 4268 C 9619 4287 9572 4283 9560 4261 C 9553 4248 9550 4000 9550 3525 C 9550 2834 9549 2808 9530 2771 C 9505 2720 9463 2686 9406 2670 C 9320 2646 9227 2691 9189 2775 C 9171 2813 9170 2873 9170 4046 C 9170 4989 9167 5279 9158 5288 C 9151 5295 9134 5300 9120 5300 C 9106 5300 9089 5295 9082 5288 C 9073 5279 9070 5167 9070 4847 C 9070 4467 9068 4414 9053 4383 C 9021 4314 8930 4289 8862 4330 C 8800 4368 8800 4368 8800 4914 C 8800 5243 8804 5427 8811 5462 C 8846 5626 8975 5760 9143 5805 C 9210 5823 9959 5826 10042 5809 Z M 7407 5608 C 7464 5580 7532 5512 7569 5447 C 7611 5373 7870 4526 7870 4463 C 7870 4402 7841 4354 7793 4333 C 7715 4301 7637 4339 7605 4424 C 7597 4447 7543 4624 7485 4819 C 7428 5014 7374 5180 7365 5189 C 7347 5207 7317 5195 7312 5167 C 7310 5159 7343 5027 7386 4874 C 7428 4720 7477 4541 7495 4475 C 7526 4363 7597 4103 7655 3895 C 7669 3846 7680 3799 7680 3793 C 7680 3783 7639 3780 7510 3780 L 7340 3780 L 7340 3287 L 7340 2793 L 7317 2750 C 7279 2677 7188 2642 7113 2671 C 7071 2686 7021 2739 7010 2780 C 7004 2801 7000 3012 7000 3298 L 7000 3780 L 6955 3780 L 6910 3780 L 6910 3279 C 6910 2928 6907 2772 6899 2757 C 6836 2635 6669 2629 6603 2745 L 6580 2785 L 6580 3283 L 6580 3780 L 6410 3780 C 6251 3780 6240 3781 6240 3799 C 6240 3809 6258 3882 6280 3961 C 6302 4040 6332 4148 6346 4200 C 6361 4252 6381 4324 6391 4360 C 6401 4396 6430 4502 6455 4595 C 6481 4689 6508 4785 6515 4810 C 6523 4835 6547 4924 6570 5008 C 6602 5126 6608 5165 6600 5180 C 6589 5200 6556 5207 6546 5191 C 6541 5184 6507 5073 6449 4875 C 6422 4784 6369 4609 6335 4495 C 6320 4446 6299 4393 6288 4377 C 6235 4302 6129 4302 6071 4376 C 6028 4431 6038 4481 6181 4948 C 6253 5183 6324 5399 6338 5428 C 6371 5496 6456 5584 6512 5610 C 6552 5628 6579 5630 6959 5630 C 7355 5630 7364 5630 7407 5608 Z M 3673 4840 C 3781 4800 3845 4706 3844 4590 C 3843 4513 3825 4467 3775 4412 C 3671 4296 3489 4297 3383 4413 C 3336 4466 3317 4513 3316 4585 C 3315 4664 3339 4725 3393 4778 C 3472 4856 3572 4878 3673 4840 Z M 8433 4840 C 8541 4800 8605 4706 8604 4590 C 8603 4513 8585 4467 8535 4412 C 8482 4353 8422 4327 8341 4327 C 8263 4327 8217 4345 8162 4395 C 8103 4447 8076 4510 8076 4590 C 8076 4706 8139 4799 8244 4839 C 8310 4865 8366 4865 8433 4840 Z M 8651 4207 C 8724 4174 8748 4133 8874 3818 C 8957 3608 8991 3514 8986 3497 C 8979 3466 8936 3424 8905 3416 C 8892 3413 8870 3414 8857 3419 C 8830 3429 8802 3494 8709 3760 L 8665 3885 L 8660 3325 C 8654 2703 8657 2722 8587 2680 C 8526 2643 8435 2664 8399 2724 C 8382 2752 8380 2778 8380 2998 C 8380 3249 8376 3280 8340 3280 C 8304 3280 8300 3249 8300 2999 C 8300 2774 8299 2755 8280 2725 C 8223 2632 8085 2642 8040 2743 C 8021 2783 8020 2814 8020 3335 C 8020 3648 8016 3880 8011 3875 C 8003 3866 7945 3685 7888 3495 C 7853 3379 7787 3339 7723 3394 C 7681 3430 7686 3471 7754 3645 C 7942 4125 7978 4188 8080 4219 C 8101 4225 8213 4228 8365 4226 C 8571 4224 8621 4221 8651 4207 Z" style="paint-order: fill;"></path>
10
+ </g>
11
+ </svg>