decidim 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of decidim might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.babelrc +2 -1
- data/.ruby-version +1 -1
- data/.travis.yml +4 -6
- data/Dockerfile +2 -2
- data/Gemfile +1 -1
- data/Gemfile.lock +48 -48
- data/README.md +6 -1
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_decidim.scss +9 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_variables.scss +7 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/application.scss +2 -19
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_categories.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/{_email_preview.scss → extra/_email_preview.scss} +0 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/{_login.scss → extra/_login.scss} +0 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_select_multiple.scss +3 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/extra/_title_bar.scss +5 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_action-icon.scss +13 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_buttons.scss +44 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_callouts.scss +32 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_cards.scss +36 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_char-counter.scss +20 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_component-counter.scss +17 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_forms.scss +80 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_icons.scss +65 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_layout.scss +67 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_main-nav.scss +41 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_modules.scss +24 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_process-header.scss +11 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_secondary-nav.scss +95 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_table-list.scss +78 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_tabs.scss +49 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_title-bar.scss +32 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_typography.scss +15 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/modules/_user-login.scss +23 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_fontface.scss +27 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_helpers.scss +25 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_keyframes.scss +21 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_mixins.scss +20 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_settings.scss +590 -0
- data/decidim-admin/app/assets/stylesheets/decidim/admin/utils/_toggle-expand.scss +8 -0
- data/decidim-admin/app/commands/decidim/admin/create_attachment.rb +13 -4
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process.rb +3 -3
- data/decidim-admin/app/commands/decidim/admin/update_participatory_process_admin.rb +40 -0
- data/decidim-admin/app/controllers/decidim/admin/application_controller.rb +7 -1
- data/decidim-admin/app/controllers/decidim/admin/newsletters_controller.rb +1 -1
- data/decidim-admin/app/controllers/decidim/admin/organization_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_process_user_roles_controller.rb +29 -0
- data/decidim-admin/app/controllers/decidim/admin/participatory_processes_controller.rb +2 -2
- data/decidim-admin/app/controllers/decidim/admin/scopes_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/static_pages_controller.rb +2 -0
- data/decidim-admin/app/controllers/decidim/admin/user_groups_controller.rb +3 -1
- data/decidim-admin/app/controllers/decidim/admin/users_controller.rb +1 -1
- data/decidim-admin/app/helpers/decidim/admin/application_helper.rb +8 -0
- data/decidim-admin/app/helpers/decidim/admin/icon_link_helper.rb +30 -0
- data/decidim-admin/app/jobs/decidim/admin/newsletter_job.rb +1 -1
- data/decidim-admin/app/queries/decidim/admin/process_admin_roles_for_process.rb +1 -1
- data/decidim-admin/app/views/decidim/admin/attachments/_form.html.erb +29 -8
- data/decidim-admin/app/views/decidim/admin/attachments/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/attachments/index.html.erb +45 -35
- data/decidim-admin/app/views/decidim/admin/attachments/new.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/categories/_form.html.erb +18 -10
- data/decidim-admin/app/views/decidim/admin/categories/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/categories/index.html.erb +57 -42
- data/decidim-admin/app/views/decidim/admin/categories/new.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/dashboard/show.html.erb +6 -3
- data/decidim-admin/app/views/decidim/admin/features/_feature.html.erb +11 -11
- data/decidim-admin/app/views/decidim/admin/features/_form.html.erb +56 -48
- data/decidim-admin/app/views/decidim/admin/features/edit.html.erb +3 -5
- data/decidim-admin/app/views/decidim/admin/features/index.html.erb +21 -19
- data/decidim-admin/app/views/decidim/admin/features/new.html.erb +3 -4
- data/decidim-admin/app/views/decidim/admin/moderations/index.html.erb +71 -61
- data/decidim-admin/app/views/decidim/admin/newsletters/_form.html.erb +7 -1
- data/decidim-admin/app/views/decidim/admin/newsletters/edit.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/newsletters/index.html.erb +50 -43
- data/decidim-admin/app/views/decidim/admin/newsletters/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/newsletters/show.html.erb +20 -12
- data/decidim-admin/app/views/decidim/admin/organization/_form.html.erb +98 -62
- data/decidim-admin/app/views/decidim/admin/organization/edit.html.erb +11 -8
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/_form.html.erb +4 -4
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/edit.html.erb +15 -9
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/index.html.erb +37 -35
- data/decidim-admin/app/views/decidim/admin/participatory_process_groups/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/_form.html.erb +21 -11
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/edit.html.erb +3 -4
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/index.html.erb +60 -51
- data/decidim-admin/app/views/decidim/admin/participatory_process_steps/new.html.erb +4 -5
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/_form.html.erb +23 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/edit.html.erb +7 -0
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/index.html.erb +46 -34
- data/decidim-admin/app/views/decidim/admin/participatory_process_user_roles/new.html.erb +7 -0
- data/decidim-admin/app/views/decidim/admin/participatory_processes/_form.html.erb +103 -72
- data/decidim-admin/app/views/decidim/admin/participatory_processes/edit.html.erb +15 -17
- data/decidim-admin/app/views/decidim/admin/participatory_processes/index.html.erb +52 -43
- data/decidim-admin/app/views/decidim/admin/participatory_processes/new.html.erb +6 -5
- data/decidim-admin/app/views/decidim/admin/scopes/edit.html.erb +9 -7
- data/decidim-admin/app/views/decidim/admin/scopes/index.html.erb +37 -36
- data/decidim-admin/app/views/decidim/admin/scopes/new.html.erb +9 -6
- data/decidim-admin/app/views/decidim/admin/static_pages/_form.html.erb +3 -3
- data/decidim-admin/app/views/decidim/admin/static_pages/edit.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/static_pages/index.html.erb +38 -37
- data/decidim-admin/app/views/decidim/admin/static_pages/new.html.erb +10 -8
- data/decidim-admin/app/views/decidim/admin/user_groups/index.html.erb +37 -31
- data/decidim-admin/app/views/decidim/admin/users/_form.html.erb +5 -4
- data/decidim-admin/app/views/decidim/admin/users/index.html.erb +57 -52
- data/decidim-admin/app/views/decidim/admin/users/new.html.erb +10 -7
- data/decidim-admin/app/views/layouts/decidim/admin/_application.html.erb +23 -36
- data/decidim-admin/app/views/layouts/decidim/admin/_callouts_full.html.erb +10 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_language_chooser.html.erb +9 -9
- data/decidim-admin/app/views/layouts/decidim/admin/_main_nav.html.erb +11 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_template_bottom.html.erb +2 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_template_top.html.erb +3 -0
- data/decidim-admin/app/views/layouts/decidim/admin/_title_bar.html.erb +20 -0
- data/decidim-admin/app/views/layouts/decidim/admin/newsletters.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/pages.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_process.html.erb +55 -53
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_process_groups.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/participatory_processes.html.erb +14 -0
- data/decidim-admin/app/views/layouts/decidim/admin/settings.html.erb +19 -0
- data/decidim-admin/app/views/layouts/decidim/admin/users.html.erb +21 -0
- data/decidim-admin/config/i18n-tasks.yml +1 -0
- data/decidim-admin/config/locales/ca.yml +77 -22
- data/decidim-admin/config/locales/en.yml +75 -20
- data/decidim-admin/config/locales/es.yml +77 -22
- data/decidim-admin/config/locales/eu.yml +191 -16
- data/decidim-admin/config/locales/fi.yml +0 -29
- data/decidim-admin/config/routes.rb +1 -1
- data/decidim-admin/lib/decidim/admin/test/manage_attachments_examples.rb +11 -11
- data/decidim-admin/spec/commands/deliver_newsletter_spec.rb +4 -1
- data/decidim-admin/spec/commands/update_participatory_process_spec.rb +117 -0
- data/decidim-admin/spec/features/admin_invite_spec.rb +5 -1
- data/decidim-admin/spec/features/admin_manages_feature_permissions_spec.rb +1 -1
- data/decidim-admin/spec/features/admin_manages_features_spec.rb +10 -10
- data/decidim-admin/spec/features/admin_manages_newsletters_spec.rb +11 -9
- data/decidim-admin/spec/features/admin_manages_organization_admins_spec.rb +8 -5
- data/decidim-admin/spec/features/admin_manages_organization_scopes_spec.rb +7 -6
- data/decidim-admin/spec/features/admin_manages_organization_spec.rb +14 -0
- data/decidim-admin/spec/features/admin_manages_participatory_process_groups_spec.rb +6 -6
- data/decidim-admin/spec/features/admin_manages_participatory_processes_spec.rb +27 -5
- data/decidim-admin/spec/features/admin_manages_user_groups_spec.rb +1 -1
- data/decidim-admin/spec/features/participatory_process_admin_manages_participatory_process_admins_spec.rb +2 -2
- data/decidim-admin/spec/features/static_pages_spec.rb +9 -7
- data/decidim-admin/spec/jobs/newsletter_job_spec.rb +2 -0
- data/decidim-admin/spec/queries/process_admin_roles_for_process_spec.rb +4 -3
- data/decidim-admin/spec/shared/manage_process_admins_examples.rb +31 -8
- data/decidim-admin/spec/shared/manage_process_attachments_examples.rb +1 -1
- data/decidim-admin/spec/shared/manage_process_categories_examples.rb +11 -26
- data/decidim-admin/spec/shared/manage_process_steps_examples.rb +8 -23
- data/decidim-admin/spec/shared/manage_processes_examples.rb +5 -33
- data/decidim-admin/spec/support/processes_menu_links_helpers.rb +1 -1
- data/decidim-admin/yarn.lock +4 -0
- data/decidim-api/app/controllers/decidim/api/application_controller.rb +2 -1
- data/decidim-budgets/app/controllers/decidim/budgets/admin/projects_controller.rb +1 -1
- data/decidim-budgets/app/controllers/decidim/budgets/line_items_controller.rb +21 -15
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/_form.html.erb +34 -24
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/edit.html.erb +3 -5
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/index.html.erb +52 -34
- data/decidim-budgets/app/views/decidim/budgets/admin/projects/new.html.erb +4 -5
- data/decidim-budgets/app/views/decidim/budgets/projects/_filters.html.erb +1 -1
- data/decidim-budgets/config/i18n-tasks.yml +1 -0
- data/decidim-budgets/config/locales/ca.yml +5 -0
- data/decidim-budgets/config/locales/en.yml +5 -0
- data/decidim-budgets/config/locales/es.yml +5 -0
- data/decidim-budgets/config/locales/eu.yml +27 -0
- data/decidim-budgets/spec/features/orders_spec.rb +22 -0
- data/decidim-budgets/spec/shared/manage_attachments_examples.rb +1 -1
- data/decidim-budgets/spec/shared/manage_projects_examples.rb +10 -8
- data/decidim-comments/README.md +33 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/bundle.js +0 -0
- data/decidim-comments/app/assets/javascripts/decidim/comments/comments.js.erb +2 -0
- data/decidim-comments/app/frontend/application/{apollo_client.js → apollo_client.ts} +5 -5
- data/decidim-comments/app/frontend/application/application.component.test.tsx +36 -0
- data/decidim-comments/app/frontend/application/application.component.tsx +37 -0
- data/decidim-comments/app/frontend/application/icon.component.test.tsx +49 -0
- data/decidim-comments/app/frontend/application/icon.component.tsx +35 -0
- data/decidim-comments/app/frontend/comments/{add_comment_form.component.test.jsx → add_comment_form.component.test.tsx} +98 -92
- data/decidim-comments/app/frontend/comments/{add_comment_form.component.jsx → add_comment_form.component.tsx} +152 -153
- data/decidim-comments/app/frontend/comments/{comment.component.test.jsx → comment.component.test.tsx} +59 -71
- data/decidim-comments/app/frontend/comments/{comment.component.jsx → comment.component.tsx} +114 -116
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.tsx +21 -0
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.tsx +88 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.tsx +65 -0
- data/decidim-comments/app/frontend/comments/comment_thread.component.tsx +70 -0
- data/decidim-comments/app/frontend/comments/{comments.component.test.jsx → comments.component.test.tsx} +38 -81
- data/decidim-comments/app/frontend/comments/{comments.component.jsx → comments.component.tsx} +49 -63
- data/decidim-comments/app/frontend/comments/down_vote_button.component.test.tsx +39 -0
- data/decidim-comments/app/frontend/comments/down_vote_button.component.tsx +89 -0
- data/decidim-comments/app/frontend/comments/up_vote_button.component.test.tsx +39 -0
- data/decidim-comments/app/frontend/comments/up_vote_button.component.tsx +89 -0
- data/decidim-comments/app/frontend/comments/vote_button.component.tsx +36 -0
- data/decidim-comments/app/frontend/comments/{vote_button_component.test.jsx → vote_button_component.test.tsx} +16 -20
- data/decidim-comments/app/frontend/entry.ts +19 -0
- data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_commentable.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/{comments → fragments}/add_comment_form_session.fragment.graphql +1 -1
- data/decidim-comments/app/frontend/{comments → fragments}/comment.fragment.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → fragments}/comment_data.fragment.graphql +6 -3
- data/decidim-comments/app/frontend/{comments → fragments}/comment_thread.fragment.graphql +3 -1
- data/decidim-comments/app/frontend/{comments/down_vote.fragment.graphql → fragments/down_vote_button.fragment.graphql} +2 -2
- data/decidim-comments/app/frontend/{comments/up_vote.fragment.graphql → fragments/up_vote_button.fragment.graphql} +2 -2
- data/decidim-comments/app/frontend/{comments/add_comment_form.mutation.graphql → mutations/add_comment.mutation.graphql} +3 -1
- data/decidim-comments/app/frontend/{comments → mutations}/down_vote.mutation.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → mutations}/up_vote.mutation.graphql +3 -1
- data/decidim-comments/app/frontend/{comments → queries}/comments.query.graphql +4 -1
- data/decidim-comments/app/frontend/support/{asset_url.js → asset_url.ts} +1 -1
- data/decidim-comments/app/frontend/support/{generate_comments_data.js → generate_comments_data.ts} +11 -6
- data/decidim-comments/app/frontend/support/{generate_user_data.js → generate_user_data.ts} +2 -2
- data/decidim-comments/app/frontend/support/{generate_user_group_data.js → generate_user_group_data.ts} +2 -2
- data/decidim-comments/app/frontend/support/graphql_transformer.js +32 -0
- data/decidim-comments/app/frontend/support/load_translations.ts +44 -0
- data/decidim-comments/app/frontend/support/{require_all.js → require_all.ts} +1 -1
- data/decidim-comments/app/frontend/support/{resolve_graphql_query.js → resolve_graphql_query.ts} +7 -7
- data/decidim-comments/app/frontend/support/schema.ts +119 -0
- data/decidim-comments/config/locales/eu.yml +29 -5
- data/decidim-dev/Rakefile +2 -0
- data/decidim-dev/config/locales/eu.yml +1 -1
- data/decidim-dev/decidim-dev.gemspec +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/capybara.rb +1 -4
- data/decidim-dev/lib/decidim/dev/test/rspec_support/feature.rb +1 -0
- data/decidim-dev/lib/decidim/dev/test/rspec_support/helpers.rb +1 -1
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/phantomjs-shim.js +215 -0
- data/decidim-dev/lib/decidim/dev/test/rspec_support/translation_helpers.rb +1 -1
- data/decidim-dev/lib/generators/decidim/dummy_generator.rb +5 -0
- data/decidim-meetings/app/controllers/decidim/meetings/admin/application_controller.rb +1 -1
- data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/_form.html.erb +30 -19
- data/decidim-meetings/app/views/decidim/meetings/admin/meeting_closes/edit.html.erb +3 -5
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/_form.html.erb +46 -35
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/edit.html.erb +5 -6
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/index.html.erb +72 -51
- data/decidim-meetings/app/views/decidim/meetings/admin/meetings/new.html.erb +4 -6
- data/decidim-meetings/app/views/decidim/meetings/meetings/_filters.html.erb +1 -1
- data/decidim-meetings/config/locales/ca.yml +2 -1
- data/decidim-meetings/config/locales/en.yml +2 -1
- data/decidim-meetings/config/locales/es.yml +2 -1
- data/decidim-meetings/config/locales/eu.yml +25 -5
- data/decidim-meetings/config/locales/fi.yml +0 -1
- data/decidim-meetings/spec/shared/manage_attachments_examples.rb +1 -1
- data/decidim-meetings/spec/shared/manage_meetings_examples.rb +18 -16
- data/decidim-pages/app/views/decidim/pages/admin/pages/_form.html.erb +10 -3
- data/decidim-pages/app/views/decidim/pages/admin/pages/edit.html.erb +3 -5
- data/decidim-pages/config/locales/eu.yml +4 -2
- data/decidim-pages/spec/features/admin_spec.rb +1 -1
- data/decidim-proposals/app/controllers/decidim/proposals/admin/proposals_controller.rb +1 -1
- data/decidim-proposals/app/views/decidim/proposals/admin/proposal_answers/edit.html.erb +14 -8
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/_form.html.erb +28 -20
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/index.html.erb +60 -43
- data/decidim-proposals/app/views/decidim/proposals/admin/proposals/new.html.erb +3 -5
- data/decidim-proposals/app/views/decidim/proposals/proposals/_filters.html.erb +1 -1
- data/decidim-proposals/config/locales/ca.yml +3 -0
- data/decidim-proposals/config/locales/en.yml +4 -1
- data/decidim-proposals/config/locales/es.yml +3 -0
- data/decidim-proposals/config/locales/eu.yml +42 -19
- data/decidim-proposals/config/locales/fi.yml +0 -1
- data/decidim-proposals/spec/shared/manage_proposals_examples.rb +15 -13
- data/decidim-results/README.md +1 -1
- data/decidim-results/app/controllers/decidim/results/admin/results_controller.rb +1 -1
- data/decidim-results/app/views/decidim/results/admin/results/_form.html.erb +30 -21
- data/decidim-results/app/views/decidim/results/admin/results/edit.html.erb +4 -5
- data/decidim-results/app/views/decidim/results/admin/results/index.html.erb +40 -25
- data/decidim-results/app/views/decidim/results/admin/results/new.html.erb +4 -5
- data/decidim-results/app/views/decidim/results/results/_filters.html.erb +1 -1
- data/decidim-results/config/locales/ca.yml +2 -0
- data/decidim-results/config/locales/en.yml +2 -0
- data/decidim-results/config/locales/es.yml +2 -0
- data/decidim-results/config/locales/eu.yml +22 -4
- data/decidim-results/spec/shared/manage_results_examples.rb +10 -8
- data/decidim-system/config/locales/eu.yml +60 -2
- data/lib/generators/decidim/app_generator.rb +0 -4
- data/lib/generators/decidim/install_generator.rb +0 -4
- data/lib/generators/decidim/templates/README.md.erb +18 -18
- data/package.json +47 -22
- data/tsconfig.json +17 -0
- data/tslint.json +12 -0
- data/webpack.config.js +8 -6
- data/webpack.d.ts +5 -0
- data/yarn.lock +1461 -781
- metadata +119 -83
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_actions.scss +0 -8
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_forms.scss +0 -10
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_foundation_and_overrides.scss +0 -53
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_icons.scss +0 -9
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_layout.scss +0 -27
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_settings.scss +0 -566
- data/decidim-admin/app/assets/stylesheets/decidim/admin/_tables.scss +0 -21
- data/decidim-admin/app/views/layouts/decidim/admin/_login_items.html.erb +0 -8
- data/decidim-admin/app/views/layouts/decidim/admin/_sidebar.html.erb +0 -22
- data/decidim-comments/app/frontend/application/application.component.jsx +0 -37
- data/decidim-comments/app/frontend/application/application.component.test.jsx +0 -33
- data/decidim-comments/app/frontend/application/icon.component.jsx +0 -26
- data/decidim-comments/app/frontend/application/icon.component.test.jsx +0 -53
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.jsx +0 -72
- data/decidim-comments/app/frontend/comments/comment_order_selector.component.test.jsx +0 -20
- data/decidim-comments/app/frontend/comments/comment_thread.component.jsx +0 -75
- data/decidim-comments/app/frontend/comments/comment_thread.component.test.jsx +0 -83
- data/decidim-comments/app/frontend/comments/down_vote_button.component.jsx +0 -98
- data/decidim-comments/app/frontend/comments/down_vote_button.component.test.jsx +0 -48
- data/decidim-comments/app/frontend/comments/featured_comment.component.jsx +0 -23
- data/decidim-comments/app/frontend/comments/featured_comment.component.test.jsx +0 -15
- data/decidim-comments/app/frontend/comments/up_vote_button.component.jsx +0 -98
- data/decidim-comments/app/frontend/comments/up_vote_button.component.test.jsx +0 -48
- data/decidim-comments/app/frontend/comments/vote_button.component.jsx +0 -32
- data/decidim-comments/app/frontend/entry.js +0 -17
- data/decidim-comments/app/frontend/entry.test.js +0 -31
- data/decidim-comments/app/frontend/support/load_translations.js +0 -23
- data/decidim-comments/app/frontend/support/stub_component.js +0 -29
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/bind-polyfill.js +0 -18
- data/decidim-dev/lib/decidim/dev/test/rspec_support/phantomjs_polyfills/object-assign-polyfill.js +0 -24
- data/karma.conf.js +0 -45
- data/lib/generators/decidim/review_app_generator.rb +0 -53
- data/lib/generators/decidim/templates/app.json.erb +0 -16
@@ -0,0 +1,21 @@
|
|
1
|
+
import { shallow } from "enzyme";
|
2
|
+
import * as React from "react";
|
3
|
+
|
4
|
+
import CommentOrderSelector from "./comment_order_selector.component";
|
5
|
+
|
6
|
+
describe("<CommentOrderSelector />", () => {
|
7
|
+
const orderBy = "older";
|
8
|
+
const reorderComments = jasmine.createSpy("reorderComments");
|
9
|
+
|
10
|
+
it("renders a div with classes order-by__dropdown order-by__dropdown--right", () => {
|
11
|
+
const wrapper = shallow(<CommentOrderSelector reorderComments={reorderComments} defaultOrderBy={orderBy} />);
|
12
|
+
expect(wrapper.find("div.order-by__dropdown.order-by__dropdown--right")).toBeDefined();
|
13
|
+
});
|
14
|
+
|
15
|
+
it("should set state order to best_rated if user clicks on the first element", () => {
|
16
|
+
const preventDefault = jasmine.createSpy("preventDefault");
|
17
|
+
const wrapper = shallow(<CommentOrderSelector reorderComments={reorderComments} defaultOrderBy={orderBy} />);
|
18
|
+
wrapper.find("a.test").simulate("click", {preventDefault});
|
19
|
+
expect(reorderComments).toBeCalledWith("best_rated");
|
20
|
+
});
|
21
|
+
});
|
@@ -0,0 +1,88 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
|
3
|
+
const { I18n } = require("react-i18nify");
|
4
|
+
|
5
|
+
interface CommentOrderSelectorProps {
|
6
|
+
defaultOrderBy: string;
|
7
|
+
reorderComments: (orderBy: string) => void;
|
8
|
+
}
|
9
|
+
|
10
|
+
interface CommentOrderSelectorState {
|
11
|
+
orderBy: string;
|
12
|
+
}
|
13
|
+
|
14
|
+
/**
|
15
|
+
* A simple static component with the comment's order selector markup
|
16
|
+
* @class
|
17
|
+
* @augments Component
|
18
|
+
* @todo Needs a proper implementation
|
19
|
+
*/
|
20
|
+
class CommentOrderSelector extends React.Component<CommentOrderSelectorProps, CommentOrderSelectorState> {
|
21
|
+
private dropdown: HTMLUListElement;
|
22
|
+
|
23
|
+
constructor(props: CommentOrderSelectorProps) {
|
24
|
+
super(props);
|
25
|
+
|
26
|
+
this.state = {
|
27
|
+
orderBy: this.props.defaultOrderBy,
|
28
|
+
};
|
29
|
+
}
|
30
|
+
|
31
|
+
public setDropdown = (dropdown: HTMLUListElement) => this.dropdown = dropdown;
|
32
|
+
|
33
|
+
public componentDidMount() {
|
34
|
+
window.$(this.dropdown).foundation();
|
35
|
+
}
|
36
|
+
|
37
|
+
public render() {
|
38
|
+
const { orderBy } = this.state;
|
39
|
+
|
40
|
+
return (
|
41
|
+
<div className="order-by__dropdown order-by__dropdown--right">
|
42
|
+
<span className="order-by__text">{I18n.t("components.comment_order_selector.title")}</span>
|
43
|
+
<ul
|
44
|
+
className="dropdown menu"
|
45
|
+
data-dropdown-menu="data-dropdown-menu"
|
46
|
+
data-close-on-click-inside="false"
|
47
|
+
ref={this.setDropdown}
|
48
|
+
>
|
49
|
+
<li>
|
50
|
+
<a>{I18n.t(`components.comment_order_selector.order.${orderBy}`)}</a>
|
51
|
+
<ul className="menu">
|
52
|
+
<li>
|
53
|
+
<a href="" className="test" onClick={this.updateOrder("best_rated")} >
|
54
|
+
{I18n.t("components.comment_order_selector.order.best_rated")}
|
55
|
+
</a>
|
56
|
+
</li>
|
57
|
+
<li>
|
58
|
+
<a href="" onClick={this.updateOrder("recent")} >
|
59
|
+
{I18n.t("components.comment_order_selector.order.recent")}
|
60
|
+
</a>
|
61
|
+
</li>
|
62
|
+
<li>
|
63
|
+
<a href="" onClick={this.updateOrder("older")} >
|
64
|
+
{I18n.t("components.comment_order_selector.order.older")}
|
65
|
+
</a>
|
66
|
+
</li>
|
67
|
+
<li>
|
68
|
+
<a href="" onClick={this.updateOrder("most_discussed")} >
|
69
|
+
{I18n.t("components.comment_order_selector.order.most_discussed")}
|
70
|
+
</a>
|
71
|
+
</li>
|
72
|
+
</ul>
|
73
|
+
</li>
|
74
|
+
</ul>
|
75
|
+
</div>
|
76
|
+
);
|
77
|
+
}
|
78
|
+
|
79
|
+
private updateOrder = (orderBy: string) => {
|
80
|
+
return (event: React.MouseEvent<HTMLAnchorElement>) => {
|
81
|
+
event.preventDefault();
|
82
|
+
this.setState({ orderBy });
|
83
|
+
this.props.reorderComments(orderBy);
|
84
|
+
};
|
85
|
+
}
|
86
|
+
}
|
87
|
+
|
88
|
+
export default CommentOrderSelector;
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { shallow } from "enzyme";
|
2
|
+
import * as React from "react";
|
3
|
+
|
4
|
+
import { CommentFragment } from "../support/schema";
|
5
|
+
import Comment from "./comment.component";
|
6
|
+
import CommentThread from "./comment_thread.component";
|
7
|
+
|
8
|
+
import generateCommentsData from "../support/generate_comments_data";
|
9
|
+
import generateCUserData from "../support/generate_user_data";
|
10
|
+
import { loadLocaleTranslations } from "../support/load_translations";
|
11
|
+
|
12
|
+
describe("<CommentThread />", () => {
|
13
|
+
let comment: CommentFragment;
|
14
|
+
let session: any = null;
|
15
|
+
|
16
|
+
beforeEach(() => {
|
17
|
+
loadLocaleTranslations("en");
|
18
|
+
const commentsData = generateCommentsData(1);
|
19
|
+
|
20
|
+
session = {
|
21
|
+
user: generateCUserData(),
|
22
|
+
};
|
23
|
+
comment = commentsData[0];
|
24
|
+
});
|
25
|
+
|
26
|
+
describe("when comment doesn't have comments", () => {
|
27
|
+
it("should not render a title with author name", () => {
|
28
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} />);
|
29
|
+
expect(wrapper.find("h6.comment-thread__title").exists()).toBeFalsy();
|
30
|
+
});
|
31
|
+
});
|
32
|
+
|
33
|
+
describe("when comment does has comments", () => {
|
34
|
+
beforeEach(() => {
|
35
|
+
comment.hasComments = true;
|
36
|
+
});
|
37
|
+
|
38
|
+
it("should render a h6 comment-thread__title with author name", () => {
|
39
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} />);
|
40
|
+
expect(wrapper.find("h6.comment-thread__title").text()).toContain(`Conversation with ${comment.author.name}`);
|
41
|
+
});
|
42
|
+
});
|
43
|
+
|
44
|
+
describe("should render a Comment", () => {
|
45
|
+
it("and pass the session as a prop to it", () => {
|
46
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} />);
|
47
|
+
expect(wrapper.find(Comment).first().props()).toHaveProperty("session", session);
|
48
|
+
});
|
49
|
+
|
50
|
+
it("and pass comment data as a prop to it", () => {
|
51
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} />);
|
52
|
+
expect(wrapper.find(Comment).first().props()).toHaveProperty("comment", comment);
|
53
|
+
});
|
54
|
+
|
55
|
+
it("and pass the votable as a prop to it", () => {
|
56
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} votable={true} />);
|
57
|
+
expect(wrapper.find(Comment).first().props()).toHaveProperty("votable", true);
|
58
|
+
});
|
59
|
+
|
60
|
+
it("and pass the isRootComment equal true", () => {
|
61
|
+
const wrapper = shallow(<CommentThread comment={comment} session={session} votable={true} />);
|
62
|
+
expect(wrapper.find(Comment).first().props()).toHaveProperty("isRootComment", true);
|
63
|
+
});
|
64
|
+
});
|
65
|
+
});
|
@@ -0,0 +1,70 @@
|
|
1
|
+
import * as React from "react";
|
2
|
+
|
3
|
+
import Comment from "./comment.component";
|
4
|
+
|
5
|
+
import {
|
6
|
+
AddCommentFormSessionFragment,
|
7
|
+
CommentFragment,
|
8
|
+
} from "../support/schema";
|
9
|
+
|
10
|
+
const { I18n } = require("react-i18nify");
|
11
|
+
|
12
|
+
interface CommentThreadProps {
|
13
|
+
comment: CommentFragment;
|
14
|
+
session: AddCommentFormSessionFragment & {
|
15
|
+
user: any;
|
16
|
+
} | null;
|
17
|
+
votable?: boolean;
|
18
|
+
}
|
19
|
+
|
20
|
+
/**
|
21
|
+
* Define a collection of comments. It represents a conversation with multiple users.
|
22
|
+
* @class
|
23
|
+
* @augments Component
|
24
|
+
* @todo It doesn't handle multiple comments yet
|
25
|
+
*/
|
26
|
+
class CommentThread extends React.Component<CommentThreadProps, undefined> {
|
27
|
+
public static defaultProps: any = {
|
28
|
+
session: null,
|
29
|
+
votable: false,
|
30
|
+
};
|
31
|
+
|
32
|
+
public render() {
|
33
|
+
const { comment, session, votable } = this.props;
|
34
|
+
|
35
|
+
return (
|
36
|
+
<div>
|
37
|
+
{this._renderTitle()}
|
38
|
+
<div className="comment-thread">
|
39
|
+
<Comment
|
40
|
+
comment={comment}
|
41
|
+
session={session}
|
42
|
+
votable={votable}
|
43
|
+
isRootComment={true}
|
44
|
+
/>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
);
|
48
|
+
}
|
49
|
+
|
50
|
+
/**
|
51
|
+
* Render conversation title if comment has commments
|
52
|
+
* @private
|
53
|
+
* @returns {Void|DOMElement} - The conversation's title
|
54
|
+
*/
|
55
|
+
private _renderTitle() {
|
56
|
+
const { comment: { author, hasComments } } = this.props;
|
57
|
+
|
58
|
+
if (hasComments) {
|
59
|
+
return (
|
60
|
+
<h6 className="comment-thread__title">
|
61
|
+
{I18n.t("components.comment_thread.title", { authorName: author.name })}
|
62
|
+
</h6>
|
63
|
+
);
|
64
|
+
}
|
65
|
+
|
66
|
+
return null;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
|
70
|
+
export default CommentThread;
|
@@ -1,91 +1,48 @@
|
|
1
|
-
import { shallow } from
|
2
|
-
import
|
3
|
-
import gql from 'graphql-tag';
|
1
|
+
import { shallow } from "enzyme";
|
2
|
+
import * as React from "react";
|
4
3
|
|
5
|
-
import
|
6
|
-
import
|
7
|
-
import
|
8
|
-
import
|
4
|
+
import AddCommentForm from "./add_comment_form.component";
|
5
|
+
import CommentOrderSelector from "./comment_order_selector.component";
|
6
|
+
import CommentThread from "./comment_thread.component";
|
7
|
+
import { Comments, commentsQuery } from "./comments.component";
|
9
8
|
|
10
|
-
import
|
9
|
+
import generateCommentsData from "../support/generate_comments_data";
|
10
|
+
import generateUserData from "../support/generate_user_data";
|
11
|
+
import resolveGraphQLQuery from "../support/resolve_graphql_query";
|
11
12
|
|
12
|
-
import
|
13
|
-
import generateCommentsData from '../support/generate_comments_data';
|
14
|
-
import generateUserData from '../support/generate_user_data';
|
15
|
-
import resolveGraphQLQuery from '../support/resolve_graphql_query';
|
13
|
+
import { loadLocaleTranslations } from "../support/load_translations";
|
16
14
|
|
17
|
-
describe(
|
18
|
-
let commentable = {};
|
19
|
-
let session = null;
|
15
|
+
describe("<Comments />", () => {
|
16
|
+
let commentable: any = {};
|
17
|
+
let session: any = null;
|
20
18
|
const commentableId = "1";
|
21
19
|
const commentableType = "Decidim::DummyResource";
|
22
20
|
const orderBy = "older";
|
23
|
-
const reorderComments = ()
|
24
|
-
|
25
|
-
const commentThreadFragment = gql`
|
26
|
-
fragment CommentThread on Comment {
|
27
|
-
author
|
28
|
-
}
|
29
|
-
`;
|
30
|
-
|
31
|
-
const addCommentFormSessionFragment = gql`
|
32
|
-
fragment AddCommentFormSession on Session {
|
33
|
-
verifiedUserGroups {
|
34
|
-
id
|
35
|
-
}
|
36
|
-
}
|
37
|
-
`;
|
38
|
-
|
39
|
-
const addCommentFormCommentableFragment = gql`
|
40
|
-
fragment AddCommentFormCommentable on Commentable {
|
41
|
-
id
|
42
|
-
}
|
43
|
-
`;
|
44
|
-
|
45
|
-
stubComponent(CommentOrderSelector)
|
46
|
-
|
47
|
-
stubComponent(CommentThread, {
|
48
|
-
fragments: {
|
49
|
-
comment: commentThreadFragment
|
50
|
-
}
|
51
|
-
});
|
52
|
-
|
53
|
-
stubComponent(AddCommentForm, {
|
54
|
-
fragments: {
|
55
|
-
session: addCommentFormSessionFragment,
|
56
|
-
commentable: addCommentFormCommentableFragment
|
57
|
-
}
|
58
|
-
});
|
21
|
+
const reorderComments = jasmine.createSpy("reorderComments");
|
59
22
|
|
60
23
|
beforeEach(() => {
|
24
|
+
loadLocaleTranslations("en");
|
61
25
|
const userData = generateUserData();
|
62
26
|
const commentsData = generateCommentsData(15);
|
63
27
|
|
64
|
-
const
|
65
|
-
${commentsQuery}
|
66
|
-
${commentThreadFragment}
|
67
|
-
${addCommentFormSessionFragment}
|
68
|
-
${addCommentFormCommentableFragment}
|
69
|
-
`;
|
70
|
-
|
71
|
-
const result = resolveGraphQLQuery(query, {
|
28
|
+
const result = resolveGraphQLQuery(commentsQuery, {
|
72
29
|
filterResult: false,
|
73
30
|
rootValue: {
|
74
31
|
session: {
|
75
|
-
user: userData
|
32
|
+
user: userData,
|
76
33
|
},
|
77
34
|
commentable: {
|
78
35
|
acceptsNewComments: true,
|
79
36
|
commentsHaveAlignment: true,
|
80
37
|
commentsHaveVotes: true,
|
81
|
-
comments: commentsData
|
82
|
-
}
|
38
|
+
comments: commentsData,
|
39
|
+
},
|
83
40
|
},
|
84
41
|
variables: {
|
85
42
|
orderBy,
|
86
43
|
commentableId,
|
87
|
-
commentableType
|
88
|
-
}
|
44
|
+
commentableType,
|
45
|
+
},
|
89
46
|
});
|
90
47
|
|
91
48
|
session = result.session;
|
@@ -93,38 +50,38 @@ describe('<Comments />', () => {
|
|
93
50
|
});
|
94
51
|
|
95
52
|
it("renders loading-comments class and the respective loading text", () => {
|
96
|
-
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} loading />);
|
97
|
-
expect(wrapper.find(
|
98
|
-
expect(wrapper.find(
|
53
|
+
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} loading={true} />);
|
54
|
+
expect(wrapper.find(".loading-comments").exists()).toBeTruthy();
|
55
|
+
expect(wrapper.find("h2").text()).toEqual("Loading comments ...");
|
99
56
|
});
|
100
57
|
|
101
58
|
it("renders a div of id comments", () => {
|
102
59
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
103
|
-
expect(wrapper.find(
|
60
|
+
expect(wrapper.find("#comments").exists()).toBeTruthy();
|
104
61
|
});
|
105
62
|
|
106
63
|
describe("renders a CommentThread component for each comment", () => {
|
107
64
|
it("and pass filter comment data as a prop to it", () => {
|
108
65
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
109
|
-
expect(wrapper).
|
66
|
+
expect(wrapper.find(CommentThread).length).toEqual(commentable.comments.length);
|
110
67
|
wrapper.find(CommentThread).forEach((node, idx) => {
|
111
|
-
expect(node
|
68
|
+
expect(node.prop("comment")).toEqual(commentable.comments[idx]);
|
112
69
|
});
|
113
70
|
});
|
114
71
|
|
115
72
|
it("and pass the session as a prop to it", () => {
|
116
73
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
117
|
-
expect(wrapper).
|
74
|
+
expect(wrapper.find(CommentThread).length).toEqual(commentable.comments.length);
|
118
75
|
wrapper.find(CommentThread).forEach((node) => {
|
119
|
-
expect(node
|
76
|
+
expect(node.prop("session")).toEqual(session);
|
120
77
|
});
|
121
78
|
});
|
122
79
|
|
123
80
|
it("and pass the commentable 'commentsHaveVotes' property as a prop to it", () => {
|
124
81
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
125
|
-
expect(wrapper).
|
82
|
+
expect(wrapper.find(CommentThread).length).toEqual(commentable.comments.length);
|
126
83
|
wrapper.find(CommentThread).forEach((node) => {
|
127
|
-
expect(node
|
84
|
+
expect(node.prop("votable")).toBeTruthy();
|
128
85
|
});
|
129
86
|
});
|
130
87
|
});
|
@@ -132,13 +89,13 @@ describe('<Comments />', () => {
|
|
132
89
|
it("renders comments count", () => {
|
133
90
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
134
91
|
const rex = new RegExp(`${commentable.comments.length} comments`);
|
135
|
-
expect(wrapper.find(
|
92
|
+
expect(wrapper.find("h2.section-heading").text()).toMatch(rex);
|
136
93
|
});
|
137
94
|
|
138
95
|
it("renders a AddCommentForm component and pass the commentable 'commentsHaveAlignment' as a prop", () => {
|
139
96
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
140
|
-
expect(wrapper).
|
141
|
-
expect(wrapper.find(AddCommentForm)
|
97
|
+
expect(wrapper.find(AddCommentForm).length).toEqual(1);
|
98
|
+
expect(wrapper.find(AddCommentForm).prop("arguable")).toBeTruthy();
|
142
99
|
});
|
143
100
|
|
144
101
|
describe("when the commentable cannot accept new comments", () => {
|
@@ -148,24 +105,24 @@ describe('<Comments />', () => {
|
|
148
105
|
|
149
106
|
it("doesn't render an AddCommentForm component", () => {
|
150
107
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
151
|
-
expect(wrapper.find(AddCommentForm)).
|
108
|
+
expect(wrapper.find(AddCommentForm).exists()).toBeFalsy();
|
152
109
|
});
|
153
110
|
|
154
111
|
it("renders a callout message to inform the user that comments are blocked", () => {
|
155
112
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
156
|
-
expect(wrapper.find(
|
113
|
+
expect(wrapper.find(".callout.warning").text()).toContain("disabled");
|
157
114
|
});
|
158
115
|
});
|
159
116
|
|
160
117
|
describe("renders a CommentOrderSelector component", () => {
|
161
118
|
it("and pass the reorderComments as a prop to it", () => {
|
162
119
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
163
|
-
expect(wrapper.find(CommentOrderSelector)
|
120
|
+
expect(wrapper.find(CommentOrderSelector).prop("reorderComments")).toEqual(reorderComments);
|
164
121
|
});
|
165
122
|
|
166
123
|
it("and pass the orderBy as a prop to it", () => {
|
167
124
|
const wrapper = shallow(<Comments commentable={commentable} session={session} reorderComments={reorderComments} orderBy={orderBy} />);
|
168
|
-
expect(wrapper.find(CommentOrderSelector)
|
125
|
+
expect(wrapper.find(CommentOrderSelector).prop("defaultOrderBy")).toEqual("older");
|
169
126
|
});
|
170
127
|
});
|
171
128
|
});
|