merge with consul

This commit is contained in:
MaiteHdezRivas
2016-03-21 18:28:20 +01:00
36 changed files with 285 additions and 66 deletions

View File

@@ -25,7 +25,7 @@ gem 'devise', '~> 3.5.6'
gem 'omniauth'
gem 'omniauth-twitter'
gem 'omniauth-facebook', '~> 3.0.0'
gem 'omniauth-google-oauth2', '~> 0.3.0'
gem 'omniauth-google-oauth2', '~> 0.4.0'
gem 'kaminari'
gem 'ancestry'
@@ -59,6 +59,7 @@ gem 'tolk' # Web interface for translations
gem 'browser'
gem 'turnout'
gem 'redcarpet'
group :development, :test do
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
gem 'byebug'

View File

@@ -201,14 +201,14 @@ GEM
terminal-table (>= 1.5.1)
initialjs-rails (0.2.0.1)
railties (>= 3.1, < 5.0)
jquery-rails (4.1.0)
rails-dom-testing (~> 1.0)
jquery-rails (4.1.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jquery-ui-rails (5.0.5)
railties (>= 3.2.16)
json (1.8.3)
jwt (1.5.1)
jwt (1.5.3)
kaminari (0.16.3)
actionpack (>= 3.0.0)
activesupport (>= 3.0.0)
@@ -239,19 +239,19 @@ GEM
mini_portile2 (~> 2.0.0.rc2)
nori (2.6.0)
oauth (0.5.0)
oauth2 (1.1.0)
oauth2 (1.0.0)
faraday (>= 0.8, < 0.10)
jwt (~> 1.0, < 1.5.2)
jwt (~> 1.0)
multi_json (~> 1.3)
multi_xml (~> 0.5)
rack (>= 1.2, < 3)
rack (~> 1.2)
omniauth (1.3.1)
hashie (>= 1.2, < 4)
rack (>= 1.0, < 3)
omniauth-facebook (3.0.0)
omniauth-oauth2 (~> 1.2)
omniauth-google-oauth2 (0.3.1)
jwt (~> 1.0)
omniauth-google-oauth2 (0.4.1)
jwt (~> 1.5.2)
multi_json (~> 1.3)
omniauth (>= 1.1.1)
omniauth-oauth2 (>= 1.3.1)
@@ -311,7 +311,7 @@ GEM
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
raindrops (0.15.0)
rake (11.0.1)
rake (11.1.1)
redcarpet (3.3.4)
referer-parser (0.3.0)
request_store (1.3.0)
@@ -471,7 +471,7 @@ DEPENDENCIES
newrelic_rpm (~> 3.14)
omniauth
omniauth-facebook (~> 3.0.0)
omniauth-google-oauth2 (~> 0.3.0)
omniauth-google-oauth2 (~> 0.4.0)
omniauth-twitter
paranoia
pg

Binary file not shown.

View File

@@ -48,4 +48,5 @@
<glyph glyph-name="budget" unicode="&#83;" d="M33 256l223 0 0 223c-5 1-11 1-16 1-115 0-208-93-208-208 0-5 0-11 1-16z m77-146c38-48 96-78 162-78 115 0 208 93 208 208 0 66-30 124-78 162-31 26-71 42-114 45l0-223-223 0c3-43 19-83 45-114z"/>
<glyph glyph-name="notification" unicode="&#110;" d="M256 48c23 0 41 19 41 42l-82 0c0-23 18-42 41-42z m135 125l0 114c0 64-45 118-104 131l0 15c0 17-13 31-31 31-18 0-31-14-31-31l0-15c-59-13-104-67-104-131l0-114-41-42 0-21 352 0 0 21z"/>
<glyph glyph-name="no-notification" unicode="&#120;" d="M257 392c7 0 24-5 24-5 46-10 78-52 78-100l0-127 9-10 8-8-240 0 8 8 9 10 0 127c0 48 33 90 78 100 0 0 18 5 24 5m1 72c-18 0-31-14-31-31l0-15c-59-13-104-67-104-131l0-114-41-42 0-21 352 0 0 21-41 42 0 114c0 64-45 118-104 131l0 15c0 17-13 31-31 31z m41-374l-82 0c0-23 18-42 41-42 23 0 41 19 41 42z"/>
<glyph glyph-name="whatsapp" unicode="&#80;" d="M318 234c2 0 12-4 28-13 16-8 24-13 25-15 1-1 1-2 1-4 0-7-2-14-5-22-3-7-10-14-20-19-11-5-20-7-29-7-11 0-29 6-55 17-18 9-34 20-48 34-14 14-28 32-42 53-14 20-21 39-21 55l0 3c1 17 8 32 21 45 5 4 10 6 15 6 1 0 3 0 5 0 3-1 5-1 6-1 3 0 6 0 7-2 2-1 3-3 5-7 1-4 5-13 9-26 5-13 7-20 7-21 0-4-3-9-9-16-7-7-10-12-10-14 0-1 0-2 1-4 7-14 16-27 29-39 11-10 25-20 43-29 3-1 5-2 7-2 3 0 8 5 15 14 8 9 13 14 15 14z m-58-152c24 0 47 5 70 15 22 9 41 22 57 38 16 16 29 35 38 57 10 22 14 46 14 70 0 24-4 47-14 69-9 22-22 42-38 58-16 16-35 28-57 38-23 9-46 14-70 14-24 0-47-5-70-14-22-10-41-22-57-38-16-16-29-36-38-58-10-22-14-45-14-69 0-39 11-74 34-105l-23-67 69 22c31-20 63-30 99-30z m0 395c29 0 57-6 84-17 26-11 49-27 68-46 20-19 35-42 46-69 12-26 17-54 17-83 0-29-5-57-17-84-11-26-26-49-46-69-19-19-42-34-68-46-27-11-55-17-84-17-37 0-72 9-104 27l-119-38 38 116c-20 33-30 71-30 111 0 29 5 57 17 83 11 27 26 50 46 69 19 19 42 35 68 46 27 11 55 17 84 17z"/>
</font></defs></svg>

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -41,6 +41,7 @@
//= require registration_form
//= require suggest
//= require forms
//= require valuation_spending_proposal_form
var initialize_modules = function() {
App.Comments.initialize();
@@ -57,6 +58,7 @@ var initialize_modules = function() {
App.RegistrationForm.initialize();
App.Suggest.initialize();
App.Forms.initialize();
App.ValuationSpendingProposalForm.initialize();
};
$(function(){

View File

@@ -0,0 +1,32 @@
App.ValuationSpendingProposalForm =
showFeasibleFields: ->
$('#valuation_spending_proposal_edit_form #not_feasible_fields').hide('down')
$('#valuation_spending_proposal_edit_form #feasible_fields').show()
showNotFeasibleFields: ->
$('#valuation_spending_proposal_edit_form #feasible_fields').hide('down')
$('#valuation_spending_proposal_edit_form #not_feasible_fields').show()
showAllFields: ->
$('#valuation_spending_proposal_edit_form #feasible_fields').show('down')
$('#valuation_spending_proposal_edit_form #not_feasible_fields').show('down')
showFeasibilityFields: ->
feasible = $("#valuation_spending_proposal_edit_form input[type=radio][name='spending_proposal[feasible]']:checked").val()
if feasible == 'true'
App.ValuationSpendingProposalForm.showFeasibleFields()
else if feasible == 'false'
App.ValuationSpendingProposalForm.showNotFeasibleFields()
showFeasibilityFieldsOnChange: ->
$("#valuation_spending_proposal_edit_form input[type=radio][name='spending_proposal[feasible]']").change ->
App.ValuationSpendingProposalForm.showAllFields()
App.ValuationSpendingProposalForm.showFeasibilityFields()
initialize: ->
App.ValuationSpendingProposalForm.showFeasibilityFields()
App.ValuationSpendingProposalForm.showFeasibilityFieldsOnChange()
false

View File

@@ -11,4 +11,4 @@
@import "annotator.min";
@import "annotator_overrides";
@import "jquery-ui/datepicker";
@import "datepicker_overrides";
@import "datepicker_overrides";

View File

@@ -160,3 +160,6 @@
.icon-no-notification:before {
content: "\78";
}
.icon-whatsapp:before {
content: "\50";
}

View File

@@ -421,10 +421,6 @@ header {
}
}
span {
color: $border;
}
.input-group {
padding-top: $line-height/4;
@@ -879,7 +875,7 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar {
}
.user-deleted {
top: -9px;
top: -4px;
}
.user-permissions {
@@ -1388,7 +1384,7 @@ table {
}
}
.date {
.date-of-birth {
select {
float: left;
@@ -1550,6 +1546,7 @@ table {
.comment {
margin: $line-height/4 0;
position: relative;
p {
margin-bottom: 0;
@@ -1727,6 +1724,7 @@ table {
td {
padding-left: $line-height*1.5;
position: relative;
word-break: break-all;
&:before {
color: $brand;

View File

@@ -337,6 +337,20 @@
.debate-show, .proposal-show {
.social-share-full .social-share-button {
display:inline;
}
.whatsapp:before {
background-color: #43d854;
color: white;
font-size: 1.7em;
margin-left: rem-calc(0.5);
padding: rem-calc(9.5) rem-calc(9.8);
vertical-align: rem-calc(10);
}
.edit-debate, .edit-proposal {
margin-bottom: 0;
}

View File

@@ -15,7 +15,7 @@ class Admin::SpendingProposalsController < Admin::BaseController
def edit
@admins = Administrator.includes(:user).all
@valuators = Valuator.includes(:user).all.order("users.username ASC")
@valuators = Valuator.includes(:user).all.order("description ASC").order("users.email ASC")
@tags = ActsAsTaggableOn::Tag.spending_proposal_tags
end

View File

@@ -19,9 +19,15 @@ class Admin::ValuatorsController < Admin::BaseController
end
def create
@valuator.user_id = params[:user_id]
@valuator = Valuator.new(create_params)
@valuator.save
redirect_to admin_valuators_path
end
private
def create_params
params[:valuator][:description] = nil if params[:valuator][:description].blank?
params.require(:valuator).permit(:user_id, :description)
end
end

View File

@@ -0,0 +1,7 @@
module ValuatorsHelper
def valuator_label(valuator)
truncate([valuator.name, valuator.email, valuator.description].compact.join(' - '), length: 100)
end
end

View File

@@ -6,4 +6,8 @@ class Valuator < ActiveRecord::Base
has_many :spending_proposals, through: :valuation_assignments
validates :user_id, presence: true, uniqueness: true
def description_or_email
description.present? ? description : email
end
end

View File

@@ -32,7 +32,7 @@
<%= f.label :valuator_ids, t("admin.spending_proposals.edit.assigned_valuators") %>
<%= f.collection_check_boxes :valuator_ids, @valuators, :id, :email do |b| %>
<%= b.label(title: b.object.name) { b.check_box + b.text } %>
<%= b.label(title: valuator_label(b.object)) { b.check_box + truncate(b.object.description_or_email, length: 60) } %>
<% end %>
<p class="clear">

View File

@@ -1,7 +1,24 @@
<span><%= valuator.name %></span>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span><%= valuator.email %></span>
<% unless valuator.persisted? %>
<%= link_to t('admin.valuators.valuator.add'),{ controller: "admin/valuators", action: :create, user_id: valuator.user_id },
method: :post, class: "button small success float-right" %>
<% end %>
<h3><%= t('admin.valuators.valuator.user_found') %>:</h3>
<div class="row">
<div class="small-12 medium-12 column">
<h4>
<%= valuator.name %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<%= valuator.email %>
</h4>
</div>
<% unless @valuator.persisted? %>
<%= form_for @valuator, url: admin_valuators_path do |f| %>
<div class="row">
<div class="small-12 medium-4 column ">
<%= f.text_field :description, label: false, placeholder: t('admin.valuators.valuator.description_placeholder') %>
<%= f.hidden_field :user_id %>
</div>
<div class="small-12 medium-2 column end" style="border:ddotted 10px red;">
<%= f.submit t('admin.valuators.valuator.add'), class: "button success float-left" %>
</div>
</div>
<% end %>
<% end %>
</div>

View File

@@ -16,7 +16,13 @@
<ul id="valuators" class="admin-list">
<% @valuators.each do |valuator| %>
<li>
<%= render 'valuator', valuator: valuator %>
<span><%= valuator.name %></span>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span><%= valuator.email %></span>
<% if valuator.description.present? %>
<span class="bullet">&nbsp;&bull;&nbsp;</span>
<span><%= valuator.description %></span>
<% end %>
</li>
<% end %>
</ul>

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j render 'valuator', valuator: @valuator %></div>");
$("#search-result").html("<%= j render 'valuator', valuator: @valuator %>");

View File

@@ -1 +1 @@
$("#search-result").html("<div class=\"panel column\"><%= j t('admin.valuators.search.user_not_found') %></div>");
$("#search-result").html("<h4><%= j t('admin.valuators.search.user_not_found') %></h4>");

View File

@@ -54,8 +54,14 @@
</div>
<div class="sidebar-divider"></div>
<h3><%= t("debates.show.share") %></h3>
<%= social_share_button_tag(@debate.title) %>
</aside>
<div class="social-share-full">
<%= social_share_button_tag(@debate.title) %>
<% if browser.mobile? %>
<a href="whatsapp://send?text=<%= @debate.title %> <%= debate_url(@debate) %>" data-action="share/whatsapp/share">
<span class="icon-whatsapp whatsapp"></span>
</a>
<% end %>
</div>
</div>
</section>
<% end %>

View File

@@ -86,7 +86,14 @@
</div>
<div class="sidebar-divider"></div>
<h3><%= t("proposals.show.share") %></h3>
<%= social_share_button_tag(@proposal.title) %>
<div class="social-share-full">
<%= social_share_button_tag(@proposal.title) %>
<% if browser.mobile? %>
<a href="whatsapp://send?text=<%= @proposal.title %> <%= proposal_url(@proposal) %>" data-action="share/whatsapp/share">
<span class="icon-whatsapp whatsapp"></span>
</a>
<% end %>
</div>
</aside>
</div>
</section>

View File

@@ -1,7 +1,7 @@
<%= link_to "#{t('valuation.spending_proposals.show.heading')} #{@spending_proposal.id}", valuation_spending_proposal_path(@spending_proposal), class: 'back' %>
<h2><%= t("valuation.spending_proposals.edit.dossier") %></h2>
<%= form_for(@spending_proposal, url: valuate_valuation_spending_proposal_path(@spending_proposal)) do |f| %>
<%= form_for(@spending_proposal, url: valuate_valuation_spending_proposal_path(@spending_proposal), html: {id: "valuation_spending_proposal_edit_form"}) do |f| %>
<%= render 'shared/errors', resource: @spending_proposal %>
<div class="row">
<div class="small-12 medium-8 column">
@@ -31,37 +31,45 @@
</div>
</div>
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :feasible_explanation, t("valuation.spending_proposals.edit.feasible_explanation_html") %>
<%= f.text_area :feasible_explanation, label: false, rows: 3 %>
<div id="not_feasible_fields" >
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :feasible_explanation, t("valuation.spending_proposals.edit.feasible_explanation_html") %>
<%= f.text_area :feasible_explanation, label: false, rows: 3 %>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-4 column">
<%= f.label :price, "#{t('valuation.spending_proposals.edit.price_html', currency: t('valuation.spending_proposals.edit.currency'))}" %>
<%= f.number_field :price, label: false, max: 1000000000000000 %>
<div id="feasible_fields">
<div class="row">
<div class="small-12 medium-4 column">
<%= f.label :price, "#{t('valuation.spending_proposals.edit.price_html', currency: t('valuation.spending_proposals.edit.currency'))}" %>
<%= f.number_field :price, label: false, max: 1000000000000000 %>
</div>
<div class="small-12 medium-4 column end">
<%= f.label :price_first_year, "#{t('valuation.spending_proposals.edit.price_first_year_html', currency: t('valuation.spending_proposals.edit.currency'))}" %>
<%= f.number_field :price_first_year, label: false, max: 1000000000000000 %>
</div>
</div>
<div class="small-12 medium-4 column end">
<%= f.label :price_first_year, "#{t('valuation.spending_proposals.edit.price_first_year_html', currency: t('valuation.spending_proposals.edit.currency'))}" %>
<%= f.number_field :price_first_year, label: false, max: 1000000000000000 %>
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :price_explanation, t("valuation.spending_proposals.edit.price_explanation_html") %>
<%= f.text_area :price_explanation, label: false, rows: 3 %>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :price_explanation, t("valuation.spending_proposals.edit.price_explanation_html") %>
<%= f.text_area :price_explanation, label: false, rows: 3 %>
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :time_scope, t("valuation.spending_proposals.edit.time_scope_html") %>
<%= f.text_field :time_scope, label: false %>
</div>
</div>
</div>
<div class="row">
<div class="small-12 medium-8 column">
<%= f.label :time_scope, t("valuation.spending_proposals.edit.time_scope_html") %>
<%= f.text_field :time_scope, label: false %>
</div>
</div>
<div class="row">

View File

@@ -40,18 +40,32 @@
<div class="row">
<div class="small-12 medium-8">
<div class="small-12 medium-4 column">
<div class="small-12 medium-3 column">
<%= f.label t("verification.residence.new.document_type_label") %>
<%= f.select :document_type, document_types, prompt: "", label: false %>
</div>
<div class="small-12 medium-5 column end">
<%= f.label t("verification.residence.new.document_number") %>
<div class="inline-block">
<%= f.label t("verification.residence.new.document_number") %>
</div>
<div class="inline-block" data-toggle="info-document-number">
<span class="icon-help"></span>
<span class="sr-only"><%= t("verification.residence.new.document_number_help_title") %></span>
</div>
<div class="dropdown-pane" id="info-document-number" data-dropdown
data-hover="true" data-hover-pane="true">
<%= t("verification.residence.new.document_number_help_text_html") %>
</div>
<%= f.text_field :document_number, label: false %>
</div>
</div>
</div>
<div class="date small-12 medium-6 clear">
<div class="date-of-birth small-12 medium-6 clear">
<%= f.label t("verification.residence.new.date_of_birth") %>
<%= f.date_select :date_of_birth,
prompt: true,
@@ -62,7 +76,9 @@
<div class="small-12 medium-5 clear">
<%= f.label t("verification.residence.new.postal_code") %>
<p class="note"><%= t("verification.residence.new.postal_code_note") %></p>
<%= f.text_field :postal_code, label: false %>
<div class="medium-6">
<%= f.text_field :postal_code, label: false %>
</div>
</div>
<div class="small-12">
@@ -78,8 +94,8 @@
<% end %>
</div>
<div class="small-12 clear">
<%= f.submit t("verification.residence.new.verify_residence"), class: "button success" %>
<div class="small-12 medium-3 clear">
<%= f.submit t("verification.residence.new.verify_residence"), class: "button success expanded" %>
</div>
<% end %>
</div>

View File

@@ -77,7 +77,9 @@ en:
index:
title: Valuators
valuator:
add: Add
description_placeholder: 'Description (optional)'
user_found: User found
add: Add to valuators
search:
email_placeholder: Search user by email
search: Search

View File

@@ -77,7 +77,9 @@ es:
index:
title: Evaluadores
valuator:
add: Añadir
description_placeholder: "Descripción (opcional)"
user_found: Usuario encontrado
add: Añadir como evaluador
search:
email_placeholder: Buscar usuario por email
search: Buscar

View File

@@ -1,5 +1,6 @@
en:
settings:
comments_body_max_length: "Comments body max length"
official_level_1_name: "Level 1 public official"
official_level_2_name: "Level 2 public official"
official_level_3_name: "Level 3 public official"

View File

@@ -1,5 +1,6 @@
es:
settings:
comments_body_max_length: "Longitud máxima de los comentarios"
official_level_1_name: "Cargos públicos de nivel 1"
official_level_2_name: "Cargos públicos de nivel 2"
official_level_3_name: "Cargos públicos de nivel 3"

View File

@@ -54,6 +54,8 @@ en:
accept_terms_text_title: I accept the terms and conditions of access of the Census
date_of_birth: Date of birth
document_number: Document number
document_number_help_title: Help
document_number_help_text_html: '<strong>DNI</strong>: 12345678A<br> <strong>Passport</strong>: AAA000001<br> <strong>Residence card</strong>: X1234567P'
document_type:
passport: Passport
residence_card: Residence card

View File

@@ -54,6 +54,8 @@ es:
accept_terms_text_title: Acepto los términos de acceso al Padrón
date_of_birth: Fecha de nacimiento
document_number: Número de documento
document_number_help_title: Ayuda
document_number_help_text_html: '<strong>DNI</strong>: 12345678A<br> <strong>Pasaporte</strong>: AAA000001<br> <strong>Tarjeta de residencia</strong>: X1234567P'
document_type:
passport: Pasaporte
residence_card: Tarjeta de residencia

View File

@@ -0,0 +1,5 @@
class AddDescriptionToValuators < ActiveRecord::Migration
def change
add_column :valuators, :description, :string
end
end

View File

@@ -435,6 +435,7 @@ ActiveRecord::Schema.define(version: 20160315084335) do
create_table "valuators", force: :cascade do |t|
t.integer "user_id"
t.string "description"
end
add_index "valuators", ["user_id"], name: "index_valuators_on_user_id", using: :btree

View File

@@ -20,9 +20,12 @@ feature 'Admin valuators' do
click_button 'Search'
expect(page).to have_content @user.name
click_link 'Add'
fill_in 'valuator_description', with: 'environmental expert'
click_button 'Add to valuators'
within("#valuators") do
expect(page).to have_content @user.name
expect(page).to have_content 'environmental expert'
end
end

View File

@@ -288,6 +288,60 @@ feature 'Valuation spending proposals' do
expect(find "#spending_proposal_feasible_nil").to be_checked
end
scenario 'Feasibility selection makes proper fields visible', :js do
feasible_true_fields = ['Price (€)','Cost during the first year (€)','Price explanation','Time scope']
feasible_false_fields = ['Feasibility explanation']
feasible_any_fields = ['Valuation finished','Internal comments']
feasible_nil_fields = feasible_true_fields + feasible_false_fields + feasible_any_fields
visit edit_valuation_spending_proposal_path(@spending_proposal)
expect(find "#spending_proposal_feasible_nil").to be_checked
feasible_nil_fields.each do |field|
expect(page).to have_content(field)
end
choose 'spending_proposal_feasible_true'
feasible_false_fields.each do |field|
expect(page).to_not have_content(field)
end
(feasible_true_fields + feasible_any_fields).each do |field|
expect(page).to have_content(field)
end
choose 'spending_proposal_feasible_false'
feasible_true_fields.each do |field|
expect(page).to_not have_content(field)
end
(feasible_false_fields + feasible_any_fields).each do |field|
expect(page).to have_content(field)
end
click_button 'Save changes'
visit edit_valuation_spending_proposal_path(@spending_proposal)
expect(find "#spending_proposal_feasible_false").to be_checked
feasible_true_fields.each do |field|
expect(page).to_not have_content(field)
end
(feasible_false_fields + feasible_any_fields).each do |field|
expect(page).to have_content(field)
end
choose 'spending_proposal_feasible_nil'
feasible_nil_fields.each do |field|
expect(page).to have_content(field)
end
end
scenario 'Finish valuation' do
visit valuation_spending_proposal_path(@spending_proposal)
click_link 'Edit dossier'

View File

@@ -0,0 +1,18 @@
require 'rails_helper'
describe Valuator do
describe "#description_or_email" do
it "should return description if present" do
valuator = create(:valuator, description: "Urbanism manager")
expect(valuator.description_or_email).to eq("Urbanism manager")
end
it "should return email if not description present" do
valuator = create(:valuator)
expect(valuator.description_or_email).to eq(valuator.email)
end
end
end