faalis_contacts 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +339 -0
- data/README.md +3 -0
- data/Rakefile +34 -0
- data/app/assets/javascripts/faalis_contacts/application.js +1 -0
- data/app/assets/javascripts/faalis_contacts/modules/contact.js +360 -0
- data/app/assets/javascripts/faalis_contacts/modules/contact_field.js +180 -0
- data/app/assets/javascripts/faalis_contacts/modules/contact_type.js +180 -0
- data/app/controllers/api/v1/contact_fields_controller.rb +52 -0
- data/app/controllers/api/v1/contact_types_controller.rb +52 -0
- data/app/controllers/api/v1/contacts_controller.rb +71 -0
- data/app/models/contact.rb +6 -0
- data/app/models/contact_details.rb +5 -0
- data/app/models/contact_field.rb +2 -0
- data/app/models/contact_type.rb +2 -0
- data/app/views/angularjs_templates/contact/details.html +36 -0
- data/app/views/angularjs_templates/contact/index.html +62 -0
- data/app/views/angularjs_templates/contact/new.html +120 -0
- data/app/views/angularjs_templates/contact_field/details.html +12 -0
- data/app/views/angularjs_templates/contact_field/index.html +9 -0
- data/app/views/angularjs_templates/contact_field/new.html +37 -0
- data/app/views/angularjs_templates/contact_type/details.html +12 -0
- data/app/views/angularjs_templates/contact_type/index.html +9 -0
- data/app/views/angularjs_templates/contact_type/new.html +37 -0
- data/app/views/api/v1/contact_fields/create.json.jbuilder +2 -0
- data/app/views/api/v1/contact_fields/destroy.json.jbuilder +1 -0
- data/app/views/api/v1/contact_fields/index.json.jbuilder +3 -0
- data/app/views/api/v1/contact_fields/show.json.jbuilder +2 -0
- data/app/views/api/v1/contact_fields/update.json.jbuilder +2 -0
- data/app/views/api/v1/contact_types/create.json.jbuilder +2 -0
- data/app/views/api/v1/contact_types/destroy.json.jbuilder +1 -0
- data/app/views/api/v1/contact_types/index.json.jbuilder +3 -0
- data/app/views/api/v1/contact_types/show.json.jbuilder +2 -0
- data/app/views/api/v1/contact_types/update.json.jbuilder +2 -0
- data/app/views/api/v1/contacts/create.json.jbuilder +2 -0
- data/app/views/api/v1/contacts/destroy.json.jbuilder +1 -0
- data/app/views/api/v1/contacts/index.json.jbuilder +9 -0
- data/app/views/api/v1/contacts/show.json.jbuilder +7 -0
- data/app/views/api/v1/contacts/update.json.jbuilder +2 -0
- data/config/routes.rb +9 -0
- data/db/migrate/20140109115319_create_contacts.rb +15 -0
- data/db/migrate/20140111082843_create_contact_details.rb +13 -0
- data/db/migrate/20140113071029_create_contact_fields.rb +9 -0
- data/db/migrate/20140113071738_create_contact_types.rb +9 -0
- data/db/seeds.rb +9 -0
- data/lib/faalis_contacts.rb +6 -0
- data/lib/faalis_contacts/engine.rb +17 -0
- data/lib/faalis_contacts/version.rb +3 -0
- data/lib/tasks/build.rake +18 -0
- data/lib/tasks/faalis_contacts_tasks.rake +4 -0
- metadata +193 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
class API::V1::ContactsController < Faalis::APIController
|
2
|
+
before_filter :build_resource, :only => :create
|
3
|
+
load_and_authorize_resource :except => [:destory]
|
4
|
+
|
5
|
+
# GET /api/v1/contacts
|
6
|
+
def index
|
7
|
+
respond_with(@contacts)
|
8
|
+
end
|
9
|
+
|
10
|
+
def create
|
11
|
+
details = params[:contact][:details] || []
|
12
|
+
details_list = []
|
13
|
+
details.each do |detail|
|
14
|
+
contact_detail = ContactDetails.create!(:detail_field => detail[:field],
|
15
|
+
:detail_type => detail[:type],
|
16
|
+
:detail_value => detail[:value])
|
17
|
+
details_list << contact_detail
|
18
|
+
end
|
19
|
+
|
20
|
+
@contact.details = details_list
|
21
|
+
|
22
|
+
if @contact.save
|
23
|
+
respond_with(@contact)
|
24
|
+
else
|
25
|
+
respond_to do |format|
|
26
|
+
format.json { render :json => {:fields => @contact.errors}, :status => :unprocessable_entity }
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def show
|
32
|
+
respond_with(@contact)
|
33
|
+
end
|
34
|
+
|
35
|
+
def update
|
36
|
+
details = params[:contact][:details] || []
|
37
|
+
details_list = []
|
38
|
+
details.each do |detail|
|
39
|
+
contact_detail = ContactDetails.create!(:detail_field => detail[:field],
|
40
|
+
:detail_type => detail[:type],
|
41
|
+
:detail_value => detail[:value])
|
42
|
+
details_list << contact_detail
|
43
|
+
end
|
44
|
+
|
45
|
+
@contact.details = details_list
|
46
|
+
|
47
|
+
if @contact.update(resource_params)
|
48
|
+
respond_with(@contact)
|
49
|
+
else
|
50
|
+
respond_to do |format|
|
51
|
+
format.json { render :json => {:fields => @contact.errors}, :status => :unprocessable_entity }
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def destroy
|
57
|
+
ids = params[:id].split(",")
|
58
|
+
@contacts = ::Contact.where(:id => ids)
|
59
|
+
authorize! :destroy, @contacts
|
60
|
+
@contacts.destroy_all
|
61
|
+
end
|
62
|
+
|
63
|
+
def build_resource
|
64
|
+
@contact = ::Contact.new(resource_params)
|
65
|
+
end
|
66
|
+
|
67
|
+
def resource_params
|
68
|
+
params.require(:contact).permit(:id, :prefix, :first_name, :middle_name, :last_name, :suffix, :organization, :is_organization)
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<div class="details">
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<b translate>Prefix :</b> {{object.prefix}}
|
5
|
+
</p>
|
6
|
+
|
7
|
+
<p>
|
8
|
+
<b translate>First_name :</b> {{object.first_name}}
|
9
|
+
</p>
|
10
|
+
|
11
|
+
<p>
|
12
|
+
<b translate>Middle_name :</b> {{object.middle_name}}
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<p>
|
16
|
+
<b translate>Last_name :</b> {{object.last_name}}
|
17
|
+
</p>
|
18
|
+
|
19
|
+
<p>
|
20
|
+
<b translate>Suffix :</b> {{object.suffix}}
|
21
|
+
</p>
|
22
|
+
|
23
|
+
<p>
|
24
|
+
<b translate>Organization :</b> {{object.organization}}
|
25
|
+
</p>
|
26
|
+
|
27
|
+
<p>
|
28
|
+
<b translate>Is_organization :</b> {{object.is_organization}}
|
29
|
+
</p>
|
30
|
+
|
31
|
+
<ul class="button-group float-right">
|
32
|
+
<a ng-href="#/contacts/{{ object.id }}/edit" class="small">
|
33
|
+
<span class="fa fa-edit"></span> <span translated>Edit</span>
|
34
|
+
</a>
|
35
|
+
</ul>
|
36
|
+
</div>
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
<filter config="filter_config" result="contacts"></filter>
|
3
|
+
|
4
|
+
|
5
|
+
<div ng-if="bulk_edit" class="fade_anim">
|
6
|
+
<form id="bulk_form">
|
7
|
+
<fieldset class="row clearmargin">
|
8
|
+
<legend translate>Bulk Edit</legend>
|
9
|
+
<div class="row">
|
10
|
+
<div class="small-6 columns">
|
11
|
+
<label for="field_name" translate>Field Name:</label>
|
12
|
+
|
13
|
+
<select id="field_name" ng-model="field_name" ng-change="field_name_change()">
|
14
|
+
<option value="0" selected translate>-- Select a field --</option>
|
15
|
+
<option ng-repeat="field in fields" value="{{ field.name }}" data-type="{{ field.type }}" data-to="{{ field.to }}"><span translate>{{ field.title }}</span></option>
|
16
|
+
</select>
|
17
|
+
</div>
|
18
|
+
<div class="small-6 columns">
|
19
|
+
<label for="field_value" translate>Field Value:</label>
|
20
|
+
<div id="value_field">
|
21
|
+
<input id="field_value" ng-model="field_value" type="text" ng-if="current_field.type == 'string' || current_field.type == 'integer'">
|
22
|
+
<textarea id="field_value" ng-model="field_value" ng-if="current_field.type == 'text'"></textarea>
|
23
|
+
|
24
|
+
<select id="field_value" ng-model="field_value" ng-if="current_field.type == 'belongs_to'">
|
25
|
+
<option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
|
26
|
+
</select>
|
27
|
+
<select id="field_value" ng-model="field_value" ng-if="current_field.type == 'has_many'" multiple>
|
28
|
+
<option ng-repeat="item in cache[current_field.name]" value="{{ item.id }}">{{ item.name }}</option>
|
29
|
+
</select>
|
30
|
+
</div>
|
31
|
+
</div>
|
32
|
+
</div>
|
33
|
+
<div class="row progressbar-container" ng-if="view_progressbar">
|
34
|
+
<div class="small-12 columns">
|
35
|
+
<div class="progressbar">
|
36
|
+
<div id="request_filler" class="filler yellow" style="width: {{ rfiller}};"></div>
|
37
|
+
<div id="success_filler" class="filler green" style="width: {{ sfiller}};"></div>
|
38
|
+
</div>
|
39
|
+
</div>
|
40
|
+
<div class="row">
|
41
|
+
<div class="small-3 columns float-right text-right">
|
42
|
+
<small>
|
43
|
+
{{ success }} <span translate>of</span> {{ total }}<span ng-if="failed > 0"> - <span translate>field:</span><span class="text-error"> {{ failed }}</span></span>
|
44
|
+
</small>
|
45
|
+
</div>
|
46
|
+
</div>
|
47
|
+
</fieldset>
|
48
|
+
<br />
|
49
|
+
<div class="row">
|
50
|
+
<div class="small-6 columns">
|
51
|
+
<button class="btn tiny green" ng-click="bulk_save()"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
52
|
+
<button class="btn tiny red" ng-click="bulk_cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
</div>
|
56
|
+
</div>
|
57
|
+
|
58
|
+
<list-view buttons="buttons" objects="contacts" title-attribute="full_name" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
|
59
|
+
<div class="small-6 column text-left clearpadding">
|
60
|
+
<h3><i class="fa fa-group"></i> <span translate>Contacts</span></h3>
|
61
|
+
</div>
|
62
|
+
</list-view>
|
@@ -0,0 +1,120 @@
|
|
1
|
+
<section class="tabs">
|
2
|
+
<ul>
|
3
|
+
<li ng-click="activate_tab(1)" ng-class="{active: current_tab == 1, tab1: current_tab == 1}"><span translate>General</span></li> |
|
4
|
+
<li ng-click="activate_tab(2)" ng-class="{active: current_tab == 2, tab2: current_tab == 2}"><span translate>Details</span></li> |
|
5
|
+
<li ng-click="activate_tab(3)" ng-class="{active: current_tab == 3, tab3: current_tab == 3}"><span translate>Avatar</span></li> |
|
6
|
+
</ul>
|
7
|
+
</section>
|
8
|
+
|
9
|
+
<form novalidate name="form">
|
10
|
+
<div class="newform">
|
11
|
+
<fieldset class="form" ng-show="current_tab == 1">
|
12
|
+
<legend><span translate>General</span></legend>
|
13
|
+
|
14
|
+
<div class="row">
|
15
|
+
<div class="small-4 columns ">
|
16
|
+
<label><span translate>Prefix</span> :</label>
|
17
|
+
<input id="id_prefix" ng-model="prefix" name="prefix" type="text" class="rounded string_field" />
|
18
|
+
<small id="id_prefix_msg"></small>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
<div class="small-4 columns float-left small-offset-2">
|
22
|
+
<label><span translate>First name</span> :</label>
|
23
|
+
<input id="id_first_name" ng-model="first_name" name="first_name" type="text" class="rounded string_field" />
|
24
|
+
<small id="id_first_name_msg"></small>
|
25
|
+
</div>
|
26
|
+
</div>
|
27
|
+
|
28
|
+
<div class="row">
|
29
|
+
<div class="small-4 columns ">
|
30
|
+
<label><span translate>Middle name</span> :</label>
|
31
|
+
<input id="id_middle_name" ng-model="middle_name" name="middle_name" type="text" class="rounded string_field" />
|
32
|
+
<small id="id_middle_name_msg"></small>
|
33
|
+
</div>
|
34
|
+
|
35
|
+
<div class="small-4 columns float-left small-offset-2">
|
36
|
+
<label><span translate>Last name</span> :</label>
|
37
|
+
<input id="id_last_name" ng-model="last_name" name="last_name" type="text" class="rounded string_field" />
|
38
|
+
<small id="id_last_name_msg"></small>
|
39
|
+
</div>
|
40
|
+
</div>
|
41
|
+
|
42
|
+
<div class="row">
|
43
|
+
<div class="small-4 columns ">
|
44
|
+
<label><span translate>Suffix</span> :</label>
|
45
|
+
<input id="id_suffix" ng-model="suffix" name="suffix" type="text" class="rounded string_field" />
|
46
|
+
<small id="id_suffix_msg"></small>
|
47
|
+
</div>
|
48
|
+
|
49
|
+
<div class="small-4 columns float-left small-offset-2">
|
50
|
+
<label><span translate>Organization</span> :</label>
|
51
|
+
<input id="id_organization" ng-model="organization" name="organization" type="text" class="rounded string_field" />
|
52
|
+
<small id="id_organization_msg"></small>
|
53
|
+
</div>
|
54
|
+
</div>
|
55
|
+
|
56
|
+
<div class="row">
|
57
|
+
<div class="small-4 columns ">
|
58
|
+
<label><span translate>Is organization</span> :</label>
|
59
|
+
<input id="id_is_organization" ng-model="is_organization" type="checkbox" name="is_organization" class="rounded boolean_field" />
|
60
|
+
<small id="id_is_organization_msg"></small>
|
61
|
+
</div>
|
62
|
+
|
63
|
+
</fieldset>
|
64
|
+
|
65
|
+
<div class="newform">
|
66
|
+
<fieldset class="form" ng-show="current_tab == 2">
|
67
|
+
<legend><span translate>Details</span></legend>
|
68
|
+
|
69
|
+
<div class="row" ng-repeat="detail_number in details_count">
|
70
|
+
<div class="small-4 columns">
|
71
|
+
<label><span translate>Field</span> :</label>
|
72
|
+
<select name="detail_field_{{ detail_number }}" ui-select2="select2options" id="id_detail_field_{{ detail_number }}" ng-model="details[detail_number].field">
|
73
|
+
<option ng-repeat="item in detail_fields" value="{{ item.id }}" ng-select="item.id === details[detial_number].type">{{ item.name }}</option>
|
74
|
+
</select>
|
75
|
+
<small id="id_detail_field_{{ detail_number}}_msg"></small>
|
76
|
+
</div>
|
77
|
+
|
78
|
+
<div class="small-4 columns">
|
79
|
+
<label><span translate>Type</span> :</label>
|
80
|
+
<select name="detail_type_{{ detail_number }}" ui-select2="select2options" id="id_detail_type_{{ detail_number }}" ng-model="details[detail_number].type">
|
81
|
+
<option ng-repeat="item in detail_types" value="{{ item.id }}" ng-select="item.id === details[detial_number].type">{{ item.name }}</option>
|
82
|
+
</select>
|
83
|
+
<small id="id_detail_type_{{ detail_number}}_msg"></small>
|
84
|
+
</div>
|
85
|
+
|
86
|
+
<div class="small-4 columns">
|
87
|
+
<label><span translate>Value</span> :</label>
|
88
|
+
<input id="id_detail_value_{{ detail_number }}" ng-model="details[detail_number].value" type="text" name="detail_value_{{ detail_number }}" class="rounded string_field"/>
|
89
|
+
<small id="id_detail_value_{{ detail_number}}_msg"></small>
|
90
|
+
|
91
|
+
</div>
|
92
|
+
</div>
|
93
|
+
|
94
|
+
<div class="row">
|
95
|
+
<div class="small-2 columns float-right">
|
96
|
+
<span ng-click="add_another_row()" class="btn tiny green"><i class="fa fa-plus"></i></span>
|
97
|
+
<span ng-click="remove_row()" class="btn tiny red"><i class="fa fa-minus"></i></span>
|
98
|
+
</div>
|
99
|
+
</div>
|
100
|
+
</fieldset>
|
101
|
+
</div>
|
102
|
+
|
103
|
+
<div class="newform">
|
104
|
+
<fieldset class="form" ng-show="current_tab == 3">
|
105
|
+
<legend ng-if="!editing"><span translate>New Avatar</span></legend>
|
106
|
+
<legend ng-if="editing"><span translate>Edit Avatar</span></legend>
|
107
|
+
|
108
|
+
</fieldset>
|
109
|
+
</div>
|
110
|
+
</form>
|
111
|
+
|
112
|
+
|
113
|
+
<div class="row">
|
114
|
+
<div class="small-6 columns">
|
115
|
+
<button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
116
|
+
<button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
|
117
|
+
<button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
118
|
+
</div>
|
119
|
+
</div>
|
120
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="details">
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<b translate>Name :</b> {{object.name}}
|
5
|
+
</p>
|
6
|
+
|
7
|
+
<ul class="button-group float-right">
|
8
|
+
<a ng-href="#/contact_fields/{{ object.id }}/edit" class="small">
|
9
|
+
<span class="fa fa-edit"></span> <span translated>Edit</span>
|
10
|
+
</a>
|
11
|
+
</ul>
|
12
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
<filter config="filter_config" result="contact_fields"></filter>
|
3
|
+
|
4
|
+
|
5
|
+
<list-view buttons="buttons" objects="contact_fields" title-attribute="'name'" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
|
6
|
+
<div class="small-6 column text-left clearpadding">
|
7
|
+
<h3><i class="fa fa-group"></i> <span translate>Contact fields</span></h3>
|
8
|
+
</div>
|
9
|
+
</list-view>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<form novalidate name="form">
|
4
|
+
<div class="newform">
|
5
|
+
<fieldset class="form">
|
6
|
+
|
7
|
+
<legend ng-if="!editing"><span translate>New Contact fields</span></legend>
|
8
|
+
<legend ng-if="editing"><span translate>Edit Contact fields</span></legend>
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
<div class="row">
|
13
|
+
<div class="small-4 columns ">
|
14
|
+
<label><i class="inline fa fa-asterisk"></i> <span translate>Name</span> :</label>
|
15
|
+
|
16
|
+
<input id="id_name" ng-model="name" name="name" type="text" class="rounded string_field" required />
|
17
|
+
|
18
|
+
<small id="id_name_msg"></small>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
</fieldset>
|
24
|
+
</form>
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
<div class="row">
|
31
|
+
<div class="small-6 columns">
|
32
|
+
<button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
33
|
+
<button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
|
34
|
+
<button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<div class="details">
|
2
|
+
|
3
|
+
<p>
|
4
|
+
<b translate>Name :</b> {{object.name}}
|
5
|
+
</p>
|
6
|
+
|
7
|
+
<ul class="button-group float-right">
|
8
|
+
<a ng-href="#/contact_types/{{ object.id }}/edit" class="small">
|
9
|
+
<span class="fa fa-edit"></span> <span translated>Edit</span>
|
10
|
+
</a>
|
11
|
+
</ul>
|
12
|
+
</div>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
|
2
|
+
<filter config="filter_config" result="contact_types"></filter>
|
3
|
+
|
4
|
+
|
5
|
+
<list-view buttons="buttons" objects="contact_types" title-attribute="'name'" details-template="details_template" item-per-page="10" on_delete="on_delete" column_defs="columns">
|
6
|
+
<div class="small-6 column text-left clearpadding">
|
7
|
+
<h3><i class="fa fa-group"></i> <span translate>Contact types</span></h3>
|
8
|
+
</div>
|
9
|
+
</list-view>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<form novalidate name="form">
|
4
|
+
<div class="newform">
|
5
|
+
<fieldset class="form">
|
6
|
+
|
7
|
+
<legend ng-if="!editing"><span translate>New Contact types</span></legend>
|
8
|
+
<legend ng-if="editing"><span translate>Edit Contact types</span></legend>
|
9
|
+
|
10
|
+
|
11
|
+
|
12
|
+
<div class="row">
|
13
|
+
<div class="small-4 columns ">
|
14
|
+
<label><i class="inline fa fa-asterisk"></i> <span translate>Name</span> :</label>
|
15
|
+
|
16
|
+
<input id="id_name" ng-model="name" name="name" type="text" class="rounded string_field" required />
|
17
|
+
|
18
|
+
<small id="id_name_msg"></small>
|
19
|
+
</div>
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
</fieldset>
|
24
|
+
</form>
|
25
|
+
|
26
|
+
|
27
|
+
|
28
|
+
|
29
|
+
|
30
|
+
<div class="row">
|
31
|
+
<div class="small-6 columns">
|
32
|
+
<button class="btn small green" ng-click="save(false)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save</span></button>
|
33
|
+
<button class="btn small blue" ng-click="save(true)" ng-disabled="form.$invalid || !form.$dirty"><i class="fa fa-check"></i> <span translate>Save & Add Another</span></button>
|
34
|
+
<button class="btn small red" ng-click="cancel()"><i class="fa fa-times"></i> <span translate>Cancel</span></button>
|
35
|
+
</div>
|
36
|
+
</div>
|
37
|
+
</div>
|