decidim-challenges 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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>