mumuki-laboratory 6.7.7 → 7.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -5
  3. data/app/assets/javascripts/mumuki_laboratory/application/timer.js +10 -5
  4. data/app/assets/stylesheets/mumuki_laboratory/application/_modules.scss +1 -0
  5. data/app/assets/stylesheets/mumuki_laboratory/application/modules/_datepicker.scss +10 -0
  6. data/app/controllers/api/organizations_controller.rb +1 -1
  7. data/app/controllers/application_controller.rb +4 -3
  8. data/app/controllers/concerns/organizations_controller_template.rb +3 -3
  9. data/app/controllers/concerns/with_authorization.rb +2 -2
  10. data/app/controllers/invitations_controller.rb +8 -4
  11. data/app/controllers/users_controller.rb +1 -1
  12. data/app/helpers/menu_bar_helper.rb +4 -1
  13. data/app/views/errors/gone.html.erb +1 -1
  14. data/app/views/invitations/_invitation_form.html.erb +23 -0
  15. data/app/views/invitations/show.html.erb +1 -39
  16. data/app/views/users/_profile_fields.html.erb +20 -0
  17. data/app/views/users/_user_form.html.erb +11 -0
  18. data/app/views/users/show.html.erb +1 -23
  19. data/config/routes.rb +1 -1
  20. data/lib/mumuki/laboratory/locales/en.yml +5 -0
  21. data/lib/mumuki/laboratory/locales/es.yml +5 -0
  22. data/lib/mumuki/laboratory/locales/pt.yml +5 -0
  23. data/lib/mumuki/laboratory/version.rb +1 -1
  24. data/spec/controllers/exercise_solutions_controller_spec.rb +1 -1
  25. data/spec/controllers/organizations_api_controller_spec.rb +6 -6
  26. data/spec/controllers/users_api_controller_spec.rb +6 -6
  27. data/spec/dummy/db/schema.rb +8 -1
  28. data/spec/dummy/db/seeds.rb +1 -0
  29. data/spec/dummy/public/error/403.svg +218 -0
  30. data/spec/dummy/public/error/404.svg +218 -0
  31. data/spec/dummy/public/error/410.svg +218 -0
  32. data/spec/dummy/public/error/500.svg +218 -0
  33. data/spec/dummy/public/error/timeout_1.svg +1 -0
  34. data/spec/dummy/public/error/timeout_2.svg +3 -0
  35. data/spec/dummy/public/error/timeout_3.svg +1 -0
  36. data/spec/features/login_flow_spec.rb +2 -0
  37. data/spec/features/not_found_private_flow_spec.rb +4 -4
  38. data/spec/features/not_found_public_flow_spec.rb +1 -1
  39. data/spec/features/profile_flow_spec.rb +11 -10
  40. data/spec/helpers/icons_helper_spec.rb +1 -1
  41. metadata +40 -15
  42. data/app/views/users/_users_form.html.erb +0 -0
  43. data/public/error/403.svg +0 -1
  44. data/public/error/404.svg +0 -1
  45. data/public/error/500.svg +0 -1
  46. data/public/error/timeout_1.svg +0 -1
  47. data/public/error/timeout_2.svg +0 -1
  48. data/public/error/timeout_3.svg +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 59b96e3b8082bef01d50a2404ca348fbdf6857a4d8bbcd1d7691968b81899cca
4
- data.tar.gz: 875a4c259fe0fa99d06184aa55d73095d55565be8c7a71a714d466d4c6393618
3
+ metadata.gz: 1c6b1188abd55b6cc2e7513c01c50752084996a25766f20e91cedc311a4cc7d9
4
+ data.tar.gz: a871f5ae58b6ed062e4717479eac69939e21b72c60031685d51e1d8be8e8931e
5
5
  SHA512:
6
- metadata.gz: df091d3aa1279f000fb0548a9de42167d71a8145f4a67f740542740e305e51a26fe1d848ba6b5c44c6c10a5343549bd3115fe16d9dcf24e9b9ce261586b97594
7
- data.tar.gz: 70c642ce217b333880c5862e249ee18965cc570598176e56f8e4e342867044be9df15d7f57a6ad12bf98900a188211d8fdb491071d1cc21fe2911b1009c37c3d
6
+ metadata.gz: 77ecc43fcd8055f1758d657e0c99e9df742e5e74b53dbcb25beeda2e037782b18172eca551a89c37bf0d50ba6a65e302c3bfbabea36f5d97ae9ed5aeb9faa2a4
7
+ data.tar.gz: 3801ccbeccdba0c2c0698f8efeced34482031c2269e4cdc9ad03432e345793eeedb05937dd4cbc7bc9d192b44062ad9082ff9753b1be2401cc14c5f1bc31fb3a
data/README.md CHANGED
@@ -220,7 +220,7 @@ Before using the API, you must create an `ApiClient` using `rails c`, which will
220
220
 
221
221
  Before using the API, take a look to the roles hierarchy:
222
222
 
223
- ![roles hierarchy](https://yuml.me/diagram/plain/class/[Owner]%5E-[Janitor],[Owner]%5E-[Moderator],%20[Janitor]%5E-[Headmaster],%20[Headmaster]%5E-[Teacher],%20[Teacher]%5E-[Student],%20,%20[Owner]%5E-[Editor],%20[Editor]%5E-[Writer]).
223
+ ![roles hierarchy](https://yuml.me/diagram/plain/class/[Admin]%5E-[Janitor],[Admin]%5E-[Moderator],%20[Janitor]%5E-[Headmaster],%20[Headmaster]%5E-[Teacher],%20[Teacher]%5E-[Student],%20,%20[Admin]%5E-[Editor],%20[Editor]%5E-[Writer],%20[Owner]%5E-[Admin]).
224
224
 
225
225
  Permissions are bound to a scope, that states in which context the operation can be performed. Scopes are simply two-level contexts, expressed as slugss `<first>/<second>`, without any explicit semantic. They exact meaning depends on the role:
226
226
 
@@ -229,6 +229,7 @@ Permissions are bound to a scope, that states in which context the operation can
229
229
  * writer and editor: `organization/content`
230
230
  * janitor: `organization/_`
231
231
  * moderator: `organization/_`
232
+ * admin: `_/_`
232
233
  * owner: `_/_`
233
234
 
234
235
  ### Users
@@ -422,7 +423,7 @@ DELETE /course/:id/teachers/:uid
422
423
 
423
424
  #### Destroy single user
424
425
 
425
- **Minimal permission**: `owner`
426
+ **Minimal permission**: `admin`
426
427
 
427
428
  ```
428
429
  DELETE /users/:uid
@@ -454,7 +455,7 @@ DELETE /organization/:id/courses/:id
454
455
 
455
456
  #### Destroy single course
456
457
 
457
- **Minimal permission**: `owner`
458
+ **Minimal permission**: `admin`
458
459
 
459
460
  ```
460
461
  DELETE /courses/:id
@@ -543,7 +544,7 @@ post /organizations
543
544
  ```
544
545
  ... with at least the required fields.
545
546
 
546
- **Minimal permission**: `owner` of that organization
547
+ **Minimal permission**: `admin` of that organization
547
548
 
548
549
  #### Update organization
549
550
 
@@ -552,7 +553,7 @@ put /organizations/:name
552
553
  ```
553
554
  ... with a partial update.
554
555
 
555
- **Minimal permission**: `owner` of `:name`
556
+ **Minimal permission**: `admin` of `:name`
556
557
 
557
558
 
558
559
  ## Authentication Powered by Auth0
@@ -6,11 +6,16 @@ var mumuki = mumuki || {};
6
6
  var currentTime = Date.now();
7
7
  var diffTime = endTime - currentTime;
8
8
  var duration = moment.duration(diffTime, 'milliseconds');
9
- var interval = 1000;
9
+ var intervalDuration = 1000;
10
10
 
11
- setInterval(function () {
12
- duration = moment.duration(duration - interval, 'milliseconds');
13
- $('#timer').text(duration.hours() + ":" + duration.minutes() + ":" + duration.seconds())
14
- }, interval);
11
+ var interval = setInterval(function () {
12
+ duration = moment.utc(duration - intervalDuration);
13
+ if(duration.valueOf() <= 0) {
14
+ clearInterval(interval);
15
+ window.location.reload();
16
+ } else {
17
+ $('#timer').text(duration.format("HH:mm:ss"));
18
+ }
19
+ }, intervalDuration);
15
20
  };
16
21
  })(mumuki);
@@ -22,3 +22,4 @@
22
22
  @import "modules/kids_results";
23
23
  @import "modules/discussion";
24
24
  @import "modules/popover";
25
+ @import "modules/datepicker";
@@ -0,0 +1,10 @@
1
+ input[type="date"] {
2
+ &::-webkit-clear-button {
3
+ display: none;
4
+ }
5
+
6
+ &::-webkit-inner-spin-button {
7
+ display: none;
8
+ }
9
+ }
10
+
@@ -3,7 +3,7 @@ module Api
3
3
  include OrganizationsControllerTemplate
4
4
 
5
5
  before_action :authorize_janitor!, only: [:show, :index]
6
- before_action :authorize_owner!, only: [:update, :create]
6
+ before_action :authorize_admin!, only: [:update, :create]
7
7
 
8
8
  def index
9
9
  render json: { organizations: Organization.accessible_as(current_user, :janitor) }
@@ -67,9 +67,10 @@ class ApplicationController < ActionController::Base
67
67
  end
68
68
 
69
69
  def validate_user_profile!
70
- return if !current_user.has_student_granted_organizations? || current_user.profile_completed?
71
- flash.notice = I18n.t :please_fill_profile_data
72
- redirect_to user_path
70
+ unless current_user.profile_completed?
71
+ flash.notice = I18n.t :please_fill_profile_data
72
+ redirect_to user_path
73
+ end
73
74
  end
74
75
 
75
76
  def set_locale!
@@ -26,9 +26,9 @@ module OrganizationsControllerTemplate
26
26
  .require(:organization)
27
27
  .permit(:book,
28
28
  :name,
29
- *Mumukit::Platform::Organization::Profile.attributes,
30
- *Mumukit::Platform::Organization::Theme.attributes,
31
- *(Mumukit::Platform::Organization::Settings.attributes - [:login_methods]),
29
+ *Mumuki::Domain::Organization::Profile.attributes,
30
+ *Mumuki::Domain::Organization::Theme.attributes,
31
+ *(Mumuki::Domain::Organization::Settings.attributes - [:login_methods]),
32
32
  login_methods: [])
33
33
  .tap { |it| it.merge!(book: Book.find_by!(slug: it[:book])) if it[:book] }
34
34
  end
@@ -5,8 +5,8 @@ module WithAuthorization
5
5
  authorize! :janitor
6
6
  end
7
7
 
8
- def authorize_owner!
9
- authorize! :owner
8
+ def authorize_admin!
9
+ authorize! :admin
10
10
  end
11
11
 
12
12
  def authorization_slug
@@ -1,6 +1,10 @@
1
1
  class InvitationsController < ApplicationController
2
2
  before_action :authenticate!
3
3
  before_action :set_invitation!
4
+ before_action :set_user!
5
+
6
+ skip_before_action :validate_user_profile!
7
+ skip_before_action :authorize_if_private!
4
8
 
5
9
  def show
6
10
  redirect_to_organization! if current_user.student_of? @invitation.course
@@ -13,10 +17,6 @@ class InvitationsController < ApplicationController
13
17
  redirect_to_organization!
14
18
  end
15
19
 
16
- def authorize_if_private!
17
- # This controller must never be authenticated
18
- end
19
-
20
20
  private
21
21
 
22
22
  def redirect_to_organization!
@@ -31,4 +31,8 @@ class InvitationsController < ApplicationController
31
31
  @invitation = Invitation.locate!(params[:code]).unexpired
32
32
  @organization = @invitation.organization
33
33
  end
34
+
35
+ def set_user!
36
+ @user = current_user
37
+ end
34
38
  end
@@ -25,7 +25,7 @@ class UsersController < ApplicationController
25
25
  end
26
26
 
27
27
  def user_params
28
- params.require(:user).permit(:first_name, :last_name)
28
+ params.require(:user).permit(User.profile_fields)
29
29
  end
30
30
 
31
31
  def set_user!
@@ -23,7 +23,10 @@ module MenuBarHelper
23
23
  def link_to_application(icon, app_name, minimal_permissions)
24
24
  return unless current_user&.send(minimal_permissions)
25
25
  url = url_for_application(app_name)
26
+ menu_item icon, app_name, url
27
+ end
26
28
 
27
- link_to fixed_fa_icon(icon, text: t(app_name)), url, role: 'menuitem', tabindex: '-1'
29
+ def menu_item(icon, name, url)
30
+ link_to fixed_fa_icon(icon, text: t(name)), url, role: 'menuitem', tabindex: '-1'
28
31
  end
29
32
  end
@@ -1,6 +1,6 @@
1
1
  <%= render layout: 'layouts/error' do %>
2
2
  <div class="header">
3
- <img src="/astor.png">
3
+ <img class="error-code-img" src="/error/410.svg">
4
4
  </div>
5
5
  <div class="body">
6
6
  <p>
@@ -0,0 +1,23 @@
1
+ <%= form_for current_user, method: 'post', url: {action: 'join'} do |f| %>
2
+ <div class="tab-content">
3
+ <div role="tabpanel" class="tab-pane active" id="info">
4
+ <div class="row mu-tab-body">
5
+ <div class="col-md-12">
6
+ <%= render partial: 'users/profile_fields', locals: {form: f} %>
7
+ </div>
8
+ </div>
9
+ </div>
10
+ </div>
11
+ <% if @organization.terms_of_service.present? %>
12
+ <div>
13
+ <h3><%= t :terms_and_conditions %></h3>
14
+ <pre class="terms-of-service"><%= simple_format @organization.terms_of_service %></pre>
15
+ <div>
16
+ <input id="accept_terms" type="checkbox"> <span><%= t :accept_terms %></span>
17
+ </div>
18
+ </div>
19
+ <% end %>
20
+ <div>
21
+ <%= f.submit t(:confirm), id: 'confirm_data', class: 'btn btn-success', disabled: @organization.terms_of_service.present? %>
22
+ </div>
23
+ <% end %>
@@ -7,45 +7,7 @@
7
7
  <div>
8
8
  <span><%= t :please_validate %></span>
9
9
  </div>
10
-
11
- <%= form_for current_user, method: 'post', url: {action: 'join'} do |f| %>
12
-
13
- <div class="tab-content">
14
- <div role="tabpanel" class="tab-pane active" id="info">
15
- <div class="row mu-tab-body">
16
- <div class="col-md-12">
17
- <fieldset class="form-group">
18
- <div><%= f.label(t :first_name) %></div>
19
- <div><%= f.text_field :first_name, class: 'form-control' %></div>
20
- </fieldset>
21
- <fieldset class="form-group">
22
- <div><%= f.label(t :last_name) %></div>
23
- <div><%= f.text_field :last_name, class: 'form-control' %></div>
24
- </fieldset>
25
- <fieldset class="form-group">
26
- <div><%= f.label(t :email) %></div>
27
- <div><%= f.text_field :email, class: 'form-control' %></div>
28
- </fieldset>
29
- </div>
30
- </div>
31
- </div>
32
- </div>
33
-
34
- <div>
35
- <h3><%= t :terms_and_conditions %></h3>
36
-
37
- <pre class="terms-of-service"><%= simple_format @organization.terms_of_service %></pre>
38
-
39
- <div class="col-md-10">
40
- <input id="accept_terms" type="checkbox"> <span><%= t :accept_terms %></span>
41
- </div>
42
- <div class="col-md-1">
43
- <%= f.submit t(:confirm), id: 'confirm_data', class: 'btn btn-success', disabled: true %>
44
- </div>
45
- </div>
46
-
47
- <% end %>
48
-
10
+ <%= render partial: 'invitation_form' %>
49
11
  <script>
50
12
  $('#accept_terms').click(function () {
51
13
  $("#confirm_data").prop('disabled', function (i, value) {
@@ -0,0 +1,20 @@
1
+ <fieldset class="form-group">
2
+ <div><%= form.label(t :first_name) %></div>
3
+ <div><%= form.text_field :first_name, required: true, class: 'form-control' %></div>
4
+ </fieldset>
5
+ <fieldset class="form-group">
6
+ <div><%= form.label(t :last_name) %></div>
7
+ <div><%= form.text_field :last_name, required: true, class: 'form-control' %></div>
8
+ </fieldset>
9
+ <fieldset class="form-group">
10
+ <div><%= form.label(t :gender) %></div>
11
+ <div><%= form.select :gender, options_for_select(User.genders.map { |gender, _| [t(gender), gender] }, @user.gender), {}, required: true, class: 'form-control' %></div>
12
+ </fieldset>
13
+ <fieldset class="form-group">
14
+ <div><%= form.label(t :birthdate) %></div>
15
+ <div><%= form.date_field :birthdate, min: Date.new(1900), max: 3.years.ago.end_of_year, required: true, class: 'form-control' %></div>
16
+ </fieldset>
17
+ <fieldset class="form-group">
18
+ <div><%= form.label(t :email) %></div>
19
+ <div><%= form.text_field :email, readonly: true, class: 'form-control' %></div>
20
+ </fieldset>
@@ -0,0 +1,11 @@
1
+ <%= form_for :user, url: update_user_path, method: :put do |f| %>
2
+ <div class="row mu-tab-body">
3
+ <div class="col-md-4 text-center">
4
+ <%= image_tag @user.image_url, size: '250x250', class: 'img-circle' %>
5
+ </div>
6
+ <div class="col-md-8">
7
+ <%= render partial: 'profile_fields', locals: {form: f} %>
8
+ <div><%= f.submit t(:save), class: 'btn btn-success btn-block' %></div>
9
+ </div>
10
+ </div>
11
+ <% end %>
@@ -25,29 +25,7 @@
25
25
 
26
26
  <div class="tab-content">
27
27
  <div role="tabpanel" class="tab-pane active" id="info">
28
- <%= form_for :user, url: update_user_path, method: :put do |f| %>
29
- <div class="row mu-tab-body">
30
- <div class="col-md-4 text-center">
31
- <%= image_tag @user.image_url, size: '250x250', class: 'img-circle' %>
32
- </div>
33
- <div class="col-md-8">
34
- <fieldset class="form-group">
35
- <div><%= f.label(t :first_name) %></div>
36
- <div><%= f.text_field :first_name, class: 'form-control' %></div>
37
- </fieldset>
38
- <fieldset class="form-group">
39
- <div><%= f.label(t :last_name) %></div>
40
- <div><%= f.text_field :last_name, class: 'form-control' %></div>
41
- </fieldset>
42
- <fieldset class="form-group">
43
- <div><%= f.label(t :email) %></div>
44
- <div><%= f.text_field :email, readonly: true, class: 'form-control' %></div>
45
- </fieldset>
46
- <br>
47
- <div><%= f.submit t(:save), class: 'btn btn-success btn-block' %></div>
48
- </div>
49
- </div>
50
- <% end %>
28
+ <%= render partial: 'user_form' %>
51
29
  </div>
52
30
  <div role="tabpanel" class="tab-pane" id="organizations">
53
31
  <div class="row mu-tab-body">
@@ -79,7 +79,7 @@ Rails.application.routes.draw do
79
79
 
80
80
 
81
81
  namespace :api do
82
- organization_regexp = Regexp.new Mumukit::Platform::Organization::Helpers.valid_name_regex
82
+ organization_regexp = Regexp.new Mumukit::Platform::Organization.valid_name_regex
83
83
  uid_regexp = /[^\/]+/
84
84
 
85
85
  resources :users, only: [:create, :update], constraints: {id: uid_regexp}
@@ -24,6 +24,7 @@ en:
24
24
  authoring_note_with_collaborators_html: This guide's content was developed by %{authors} and <a href="%{collaborators}" target="_blank">many others</a>, under the terms of <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Creative Commons License Share-Alike, 4.0</a>
25
25
  back_to_mumuki: Back to Mumuki!
26
26
  bibliotheca_ui: Bibliotheca
27
+ birthdate: Birthdate
27
28
  blocked_forum_explanation: You are not allowed to see this content. <br> Are you in the middle of an exam right now?
28
29
  cancel_subscription: Cancel your subscription.
29
30
  chapter: Chapter
@@ -79,9 +80,11 @@ en:
79
80
  explain_redirect: You have registered in another organization
80
81
  failed: Oops, something went wrong
81
82
  feedback: Feedback
83
+ female: Female
82
84
  finish: Finish
83
85
  first_name: First Name
84
86
  forbidden_explanation: You are not allowed to see this content.
87
+ gender: Gender
85
88
  go_to: 'Go to %{organization}'
86
89
  gone_explanation: This exam is no longer available.
87
90
  guide: Guide
@@ -110,6 +113,7 @@ en:
110
113
  lesson_number: Lesson %{number}
111
114
  let_us_know: please let us know!
112
115
  load_solution_into_console: Load your solution into the console
116
+ male: Male
113
117
  manual_evaluation_pending: Thanks for submitting your solution! It will be revised by the course teachers soon
114
118
  message_count:
115
119
  one: 1 message
@@ -147,6 +151,7 @@ en:
147
151
  office: Office
148
152
  opened: Open
149
153
  opened_count: '%{count} opened'
154
+ other: Other
150
155
  out_of_attempts: You've run out of attempts. You should proceed to the next exercise!
151
156
  output: Output
152
157
  overview: Overview
@@ -26,6 +26,7 @@ es:
26
26
  authoring_note_with_collaborators_html: Esta guía fue desarrollada por %{authors} y <a href="%{collaborators}" target="_blank">muchas personas más</a>, bajo los términos de la <a href="https://creativecommons.org/licenses/by-sa/4.0/" target="_blank">Licencia Creative Commons Compartir-Igual, 4.0</a>.
27
27
  back_to_mumuki: ¡Volvé a Mumuki!
28
28
  bibliotheca_ui: Biblioteca
29
+ birthdate: Fecha de nacimiento
29
30
  blocked_forum_explanation: Es decir que no tenés autorización para ver este contenido. <br> ¿Puede que estés en medio de un examen?
30
31
  cancel_subscription: Cancelá tu subscripción.
31
32
  chapter: Capítulo
@@ -87,9 +88,11 @@ es:
87
88
  explain_redirect: Notamos que te registraste en otra organización.
88
89
  failed: Tu solución no pasó las pruebas
89
90
  feedback: Problemas que encontramos
91
+ female: Mujer
90
92
  finish: Terminar
91
93
  first_name: Nombre
92
94
  forbidden_explanation: Es decir que no tenés autorización para ver este contenido. <br> ¿Puede que hayas ingresado con una cuenta incorrecta?
95
+ gender: Género
93
96
  go_to: 'Ir a %{organization}'
94
97
  gone_explanation: ¡Ups! Esto es lo que se conoce como %{error}, es decir que ya no podés ver este examen.
95
98
  guide: Lección
@@ -122,6 +125,7 @@ es:
122
125
  lesson_number: Lección %{number}
123
126
  let_us_know: ¡Por favor avisanos!
124
127
  load_solution_into_console: Cargar la solución en la consola
128
+ male: Hombre
125
129
  manual_evaluation_pending: ¡Gracias por enviar tu solución! Tus docentes la corregirán pronto
126
130
  message_count:
127
131
  one: 1 mensaje
@@ -166,6 +170,7 @@ es:
166
170
  one: '1 abierta'
167
171
  other: '%{count} abiertas'
168
172
  organizations: Organizaciones
173
+ other: Otro
169
174
  out_of_attempts: Te quedaste sin intentos. ¡Seguí al proximo ejercicio!
170
175
  output: Salida
171
176
  overview: Vista general
@@ -25,6 +25,7 @@ pt:
25
25
  authoring_note_with_collaborators_html: 'Este guia foi desenvolvido por %{authors} e <a href="%{collaborators}" target="_blank">muitas outras pessoas </a>, nos termos do <a href = "https://creativecommons.org/licenses/by-sa/4.0/" target="_blank"> Creative Commons License Share-Equal, 4.0 </a>.'
26
26
  back_to_mumuki: Voltei para Mumuki!
27
27
  bibliotheca_ui: Biblioteca
28
+ birthdate: Fecha de nacimiento
28
29
  blocked_forum_explanation: Você não tem permissão para ver este conteúdo. <br> Você está no meio de um exame agora?
29
30
  chapter: Capítulo
30
31
  chapter_finished_html: Você terminou %{chapter}! Parabéns!
@@ -82,10 +83,12 @@ pt:
82
83
  explain_redirect: Percebemos que você se registrou em outra organização.
83
84
  failed: Sua solução não passou as provas
84
85
  feedback: Problemas que encontramos
86
+ female: Feminino
85
87
  finish: Terminar
86
88
  first_name: Nome
87
89
  forbidden_explanation: Isso significa que você não tem autorização para ver esse conteúdo. <br> Você poderia ter entrado com uma conta incorreta?
88
90
  fullscreen: Tela completa
91
+ gender: Gênero
89
92
  get_messages: Ver mensagens
90
93
  go_to: Vá para %{organization}
91
94
  gone_explanation: Opa! Isto é o que é conhecido como %{error}, ou seja, você não pode mais ver esse exame.
@@ -117,6 +120,7 @@ pt:
117
120
  lesson_number: Lição %{number}
118
121
  let_us_know: Por favor, avise-nos!
119
122
  load_solution_into_console: Carregue a solução no console
123
+ male: Masculino
120
124
  manual_evaluation_pending: Obrigado por enviar sua solução! Seus professores irão corrigi-lo em breve
121
125
  message_count:
122
126
  one: 1 mensagem
@@ -158,6 +162,7 @@ pt:
158
162
  opened: Aberto
159
163
  opened_count: '%{count} aberto'
160
164
  organizations: Organizações
165
+ other: Outro
161
166
  out_of_attempts: Você ficou sem tentativas. Você deve prosseguir para o próximo exercício!
162
167
  output: Sair
163
168
  overview: Visão global