udongo 5.9.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/backend/bootstrap.js +4 -4
- data/app/assets/javascripts/backend/flexible_content.js +1 -1
- data/app/assets/javascripts/backend/flexible_content_breakpoints.js +32 -0
- data/app/assets/stylesheets/backend/bootstrap.scss +4877 -1925
- data/app/assets/stylesheets/backend/components/_card.scss +3 -0
- data/app/assets/stylesheets/backend/components/_form.scss +1 -1
- data/app/assets/stylesheets/backend/components/{_tabs.scss → _tab.scss} +0 -0
- data/app/assets/stylesheets/backend/udongo.scss +2 -1
- data/app/controllers/backend/content/rows/videos_controller.rb +6 -0
- data/app/controllers/backend/content/rows_controller.rb +22 -1
- data/app/decorators/content_row_decorator.rb +20 -0
- data/app/decorators/content_video_decorator.rb +23 -0
- data/app/helpers/backend/dropdown_helper.rb +1 -1
- data/app/models/content_video.rb +11 -0
- data/app/models/email_template.rb +1 -1
- data/app/views/backend/_breadcrumbs.html.erb +3 -2
- data/app/views/backend/_navigation.html.erb +5 -2
- data/app/views/backend/admins/index.html.erb +2 -2
- data/app/views/backend/articles/images/index.html.erb +2 -2
- data/app/views/backend/articles/index.html.erb +2 -2
- data/app/views/backend/assets/index.html.erb +2 -2
- data/app/views/backend/content/_rows.html.erb +36 -2
- data/app/views/backend/content/_video.html.erb +8 -0
- data/app/views/backend/content/rows/columns/_column_width_explanation.html.erb +5 -0
- data/app/views/backend/content/rows/columns/_dimension_fields.html.erb +28 -10
- data/app/views/backend/content/rows/columns/edit.html.erb +2 -0
- data/app/views/backend/content/rows/columns/new.html.erb +2 -0
- data/app/views/backend/content/rows/videos/edit.html.erb +14 -0
- data/app/views/backend/email_templates/index.html.erb +1 -1
- data/app/views/backend/emails/index.html.erb +1 -1
- data/app/views/backend/forms/fields/index.html.erb +10 -17
- data/app/views/backend/forms/index.html.erb +7 -9
- data/app/views/backend/forms/submissions/index.html.erb +4 -9
- data/app/views/backend/images/index.html.erb +1 -3
- data/app/views/backend/images/new.html.erb +0 -1
- data/app/views/backend/navigations/index.html.erb +2 -2
- data/app/views/backend/pages/index.html.erb +1 -1
- data/app/views/backend/redirects/index.html.erb +3 -4
- data/app/views/backend/search_synonyms/_form.html.erb +15 -7
- data/app/views/backend/search_synonyms/index.html.erb +2 -2
- data/app/views/backend/snippets/index.html.erb +1 -1
- data/app/views/backend/users/index.html.erb +2 -2
- data/app/views/layouts/backend/_top_navigation.html.erb +46 -41
- data/app/views/layouts/backend/lightbox.html.erb +5 -1
- data/changelog.md +12 -0
- data/config/locales/en_backend.yml +11 -2
- data/config/locales/nl_backend.yml +11 -2
- data/config/routes.rb +4 -0
- data/db/migrate/20170507092541_add_alignment_options_to_content_rows.rb +7 -0
- data/db/migrate/20170507163532_create_content_videos.rb +10 -0
- data/lib/udongo/configs/flexible_content.rb +2 -6
- data/lib/udongo/version.rb +1 -1
- data/readme.md +1 -6
- data/spec/factories/content_videos.rb +4 -0
- metadata +14 -3
File without changes
|
@@ -10,12 +10,13 @@
|
|
10
10
|
|
11
11
|
// Components
|
12
12
|
@import 'components/navbar';
|
13
|
-
@import 'components/
|
13
|
+
@import 'components/tab';
|
14
14
|
@import 'components/breadcrumb';
|
15
15
|
@import 'components/form';
|
16
16
|
@import 'components/nav';
|
17
17
|
@import 'components/page_tree';
|
18
18
|
@import 'components/table';
|
19
|
+
@import 'components/card';
|
19
20
|
|
20
21
|
// Page specific styles
|
21
22
|
@import 'pages/login';
|
@@ -1,6 +1,6 @@
|
|
1
1
|
class Backend::Content::RowsController < Backend::BaseController
|
2
2
|
include Concerns::Backend::PositionableController
|
3
|
-
before_action :find_model,
|
3
|
+
before_action :find_model, except: [:new]
|
4
4
|
|
5
5
|
def new
|
6
6
|
if params[:klass] && params[:id] && params[:locale]
|
@@ -13,6 +13,27 @@ class Backend::Content::RowsController < Backend::BaseController
|
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
+
def horizontal_alignment
|
17
|
+
align = params[:align].to_s
|
18
|
+
align = 'left' unless %w(left center right).include?(align)
|
19
|
+
@row.update_attribute :horizontal_alignment, align
|
20
|
+
|
21
|
+
redirect_back_to_content
|
22
|
+
end
|
23
|
+
|
24
|
+
def vertical_alignment
|
25
|
+
align = params[:align].to_s
|
26
|
+
align = 'top' unless %w(top center bottom).include?(align)
|
27
|
+
@row.update_attribute :vertical_alignment, align
|
28
|
+
|
29
|
+
redirect_back_to_content
|
30
|
+
end
|
31
|
+
|
32
|
+
def toggle_full_width
|
33
|
+
@row.update_attribute :full_width, !@row.full_width?
|
34
|
+
redirect_back_to_content
|
35
|
+
end
|
36
|
+
|
16
37
|
def destroy
|
17
38
|
@row.destroy
|
18
39
|
redirect_back_to_content('content-rows')
|
@@ -6,4 +6,24 @@ class ContentRowDecorator < ApplicationDecorator
|
|
6
6
|
def column_limit_reached?
|
7
7
|
column_width_calculator.total(:width_xl) >= 12
|
8
8
|
end
|
9
|
+
|
10
|
+
def classes
|
11
|
+
list = []
|
12
|
+
|
13
|
+
if horizontal_alignment.to_s == 'center'
|
14
|
+
list << 'justify-content-center'
|
15
|
+
|
16
|
+
elsif horizontal_alignment.to_s == 'right'
|
17
|
+
list << 'justify-content-end'
|
18
|
+
end
|
19
|
+
|
20
|
+
if vertical_alignment.to_s == 'center'
|
21
|
+
list << 'align-items-center'
|
22
|
+
|
23
|
+
elsif vertical_alignment.to_s == 'bottom'
|
24
|
+
list << 'align-items-end'
|
25
|
+
end
|
26
|
+
|
27
|
+
list
|
28
|
+
end
|
9
29
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
class ContentVideoDecorator < ApplicationDecorator
|
2
|
+
delegate_all
|
3
|
+
|
4
|
+
def embed_url
|
5
|
+
url.to_s.include?('vimeo') ? vimeo_embed_url : youtube_embed_url
|
6
|
+
end
|
7
|
+
|
8
|
+
def aspect_ratio_class
|
9
|
+
aspect_ratio.to_s.split('x').join('by')
|
10
|
+
end
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
def vimeo_embed_url
|
15
|
+
video_id = /[0-9*]+/.match(url.to_s).to_s
|
16
|
+
"https://player.vimeo.com/video/#{video_id}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def youtube_embed_url
|
20
|
+
video_id = url.to_s.split('v=').last
|
21
|
+
"https://www.youtube.com/embed/#{video_id}?rel=0"
|
22
|
+
end
|
23
|
+
end
|
@@ -4,7 +4,7 @@ class EmailTemplate < ApplicationRecord
|
|
4
4
|
|
5
5
|
include Concerns::Sortable
|
6
6
|
|
7
|
-
validates :description, :from_name, presence: true
|
7
|
+
validates :description, :from_name, :from_email, presence: true
|
8
8
|
validates :identifier, presence: true, uniqueness: { case_sensitive: false }
|
9
9
|
validates :from_email, email: true
|
10
10
|
validates :cc, :bcc, email: true, allow_blank: true
|
@@ -3,10 +3,11 @@
|
|
3
3
|
<li class="breadcrumb-item"><%= link_to icon(:home), backend_path %></li>
|
4
4
|
|
5
5
|
<% breadcrumb.each do |item| %>
|
6
|
-
<%
|
6
|
+
<% last = (item == breadcrumb.all.last) %>
|
7
|
+
<% klass = last ? 'active' : '' %>
|
7
8
|
<li class="breadcrumb-item <%= klass %>">
|
8
9
|
|
9
|
-
<% if item[:link].present? %>
|
10
|
+
<% if item[:link].present? && !last %>
|
10
11
|
<%= link_to item[:name].to_s.html_safe, item[:link] %>
|
11
12
|
<% else %>
|
12
13
|
<%= item[:name].to_s.html_safe %>
|
@@ -1,8 +1,11 @@
|
|
1
|
-
<nav class="navbar navbar-
|
1
|
+
<nav class="navbar navbar-toggleable-md navbar-inverse bg-inverse">
|
2
|
+
<button class="navbar-toggler navbar-toggler-right" type="button" data-toggle="collapse" data-target="#udongo-navbar" aria-controls="udongo-navbar" aria-expanded="false" aria-label="Toggle navigation">
|
3
|
+
<span class="navbar-toggler-icon"></span>
|
4
|
+
</button>
|
5
|
+
|
2
6
|
<%= link_to backend_path, class: 'navbar-brand' do %>
|
3
7
|
<%= Udongo.config.base.project_name %>
|
4
8
|
<% end %>
|
5
9
|
|
6
10
|
<%= render 'layouts/backend/top_navigation' %>
|
7
11
|
</nav>
|
8
|
-
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= render 'backend/breadcrumbs' %>
|
2
2
|
|
3
|
-
<p class="text-
|
3
|
+
<p class="text-right">
|
4
4
|
<%= link_to icon(:plus, t('b.add')), new_backend_admin_path, class: 'btn btn-primary btn-sm' %>
|
5
5
|
</p>
|
6
6
|
|
@@ -19,7 +19,7 @@
|
|
19
19
|
<tr>
|
20
20
|
<td><%= a.full_name %></td>
|
21
21
|
<td><%= mail_to a.email %></td>
|
22
|
-
<td class="text-
|
22
|
+
<td class="text-right">
|
23
23
|
<%= link_to_edit [:backend, a] %>
|
24
24
|
<%= link_to_delete [:backend, a] %>
|
25
25
|
</td>
|
@@ -2,7 +2,7 @@
|
|
2
2
|
<%= render 'backend/breadcrumbs' %>
|
3
3
|
<%= render 'backend/articles/tabs', model: @article, active: :images %>
|
4
4
|
|
5
|
-
<p class="text-
|
5
|
+
<p class="text-right">
|
6
6
|
<%= link_to icon(:plus, t('b.add')), backend_images_path(klass: @article.class.name, id: @article.id), class: 'btn btn-primary btn-sm' %>
|
7
7
|
</p>
|
8
8
|
|
@@ -30,7 +30,7 @@
|
|
30
30
|
<td><%= number_to_human_size a.filesize %></td>
|
31
31
|
<td><%= simple_format a.description %></td>
|
32
32
|
<td><%= l a.updated_at %></td>
|
33
|
-
<td class="text-
|
33
|
+
<td class="text-right">
|
34
34
|
<%= link_to icon(:trash), unlink_backend_images_path(klass: @article.class.name, id: @article.id, asset_id: a.id), data: { confirm: t('b.msg.confirm') }, title: t('b.delete') %>
|
35
35
|
</td>
|
36
36
|
</tr>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<%= render 'backend/breadcrumbs' %>
|
2
2
|
|
3
|
-
<p class="text-
|
3
|
+
<p class="text-right">
|
4
4
|
<%= link_to icon(:plus, t('b.add')), new_backend_article_path, class: 'btn btn-primary btn-sm' %>
|
5
5
|
</p>
|
6
6
|
|
@@ -40,7 +40,7 @@
|
|
40
40
|
<td><%= l a.published_at if a.published_at %></td>
|
41
41
|
<td><%= t a.visible?.to_s %></td>
|
42
42
|
<td><%= t a.press_release?.to_s %></td>
|
43
|
-
<td class="text-
|
43
|
+
<td class="text-right">
|
44
44
|
<%= link_to_edit_translation [:backend, a] %>
|
45
45
|
<%= link_to_delete [:backend, a] %>
|
46
46
|
</td>
|
@@ -1,7 +1,7 @@
|
|
1
1
|
<%= render 'backend/breadcrumbs' %>
|
2
2
|
<%= render 'filter' %>
|
3
3
|
|
4
|
-
<p class="text-
|
4
|
+
<p class="text-right">
|
5
5
|
<%= link_to icon(:plus, t('b.add')), new_backend_asset_path, class: 'btn btn-primary btn-sm' %>
|
6
6
|
</p>
|
7
7
|
|
@@ -32,7 +32,7 @@
|
|
32
32
|
<td><%= number_to_human_size a.filesize %></td>
|
33
33
|
<td><%= simple_format a.description %></td>
|
34
34
|
<td><%= l a.updated_at %></td>
|
35
|
-
<td class="text-
|
35
|
+
<td class="text-right">
|
36
36
|
<%= link_to_edit [:backend, a] %>
|
37
37
|
<%= link_to_delete [:backend, a] if a.deletable? %>
|
38
38
|
</td>
|
@@ -21,11 +21,45 @@
|
|
21
21
|
<div id="content-row-<%= row.id %>" class="card content-row" data-update-position="<%= update_position_backend_content_row_path(row) %>">
|
22
22
|
<div class="card-header handle">
|
23
23
|
<div class="btn-group" role="group">
|
24
|
-
|
24
|
+
<% klass = 'btn btn-secondary' %>
|
25
|
+
<% klass << ' active' if row.horizontal_alignment == 'left' || row.horizontal_alignment.blank? %>
|
26
|
+
<%= link_to icon(:align_left), horizontal_alignment_backend_content_row_path(row, align: 'left'), class: klass, title: t('b.msg.flexible_content.align_left'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
27
|
+
|
28
|
+
<% klass = 'btn btn-secondary' %>
|
29
|
+
<% klass << ' active' if row.horizontal_alignment == 'center' %>
|
30
|
+
<%= link_to icon(:align_center), horizontal_alignment_backend_content_row_path(row, align: 'center'), class: klass, title: t('b.msg.flexible_content.align_center'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
31
|
+
|
32
|
+
<% klass = 'btn btn-secondary' %>
|
33
|
+
<% klass << ' active' if row.horizontal_alignment == 'right' %>
|
34
|
+
<%= link_to icon(:align_right), horizontal_alignment_backend_content_row_path(row, align: 'right'), class: klass, title: t('b.msg.flexible_content.align_right'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
35
|
+
</div>
|
36
|
+
|
37
|
+
<div class="btn-group" role="group">
|
38
|
+
<% klass = 'btn btn-secondary' %>
|
39
|
+
<% klass << ' active' if row.vertical_alignment == 'top' || row.vertical_alignment.blank? %>
|
40
|
+
<%= link_to icon(:long_arrow_up), vertical_alignment_backend_content_row_path(row, align: 'top') , class: klass, title: t('b.msg.flexible_content.align_vertical_top'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
41
|
+
|
42
|
+
<% klass = 'btn btn-secondary' %>
|
43
|
+
<% klass << ' active' if row.vertical_alignment == 'center' %>
|
44
|
+
<%= link_to icon(:arrows_v), vertical_alignment_backend_content_row_path(row, align: 'center'), class: klass, title: t('b.msg.flexible_content.align_vertical_center'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
45
|
+
|
46
|
+
<% klass = 'btn btn-secondary' %>
|
47
|
+
<% klass << ' active' if row.vertical_alignment == 'bottom' %>
|
48
|
+
<%= link_to icon(:long_arrow_down), vertical_alignment_backend_content_row_path(row, align: 'bottom'), class: klass, title: t('b.msg.flexible_content.align_vertical_bottom'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
49
|
+
</div>
|
50
|
+
|
51
|
+
<div class="btn-group" role="group">
|
52
|
+
<% klass = 'btn btn-secondary' %>
|
53
|
+
<% klass << ' active' if row.full_width? %>
|
54
|
+
<%= link_to icon(:arrows_h), toggle_full_width_backend_content_row_path(row), class: klass, title: t('b.msg.flexible_content.full_width'), data: { toggle: 'tooltip', placement: 'bottom' } %>
|
55
|
+
</div>
|
56
|
+
|
57
|
+
<div class="btn-group" role="group">
|
58
|
+
<%= link_to icon(:trash), backend_content_row_path(row), class: 'btn btn-secondary', title: t('b.delete'), method: :delete, data: { toggle: 'tooltip', placement: 'bottom', confirm: t('b.msg.confirm') } %>
|
25
59
|
</div>
|
26
60
|
</div>
|
27
61
|
|
28
|
-
<div class="row content-columns card-block">
|
62
|
+
<div class="row content-columns card-block <%= row.classes.join(' ') %>">
|
29
63
|
<% row.columns.each do |column| %>
|
30
64
|
<% content = column.content.decorate %>
|
31
65
|
|
@@ -0,0 +1,8 @@
|
|
1
|
+
<% if object.url.present? && object.aspect_ratio.present? %>
|
2
|
+
<div class="embed-responsive embed-responsive-<%= object.aspect_ratio_class %>">
|
3
|
+
<iframe class="embed-responsive-item" src="<%= object.embed_url %>" allowfullscreen></iframe>
|
4
|
+
</div>
|
5
|
+
|
6
|
+
<% else %>
|
7
|
+
<p><%= t 'b.msg.flexible_content.no_video_present' %></p>
|
8
|
+
<% end %>
|
@@ -1,11 +1,29 @@
|
|
1
|
-
<%
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
1
|
+
<% javascript 'backend/flexible_content_breakpoints' %>
|
2
|
+
|
3
|
+
<% Udongo::Configs::FlexibleContent::BREAKPOINTS.each do |b| %>
|
4
|
+
<% if b == Udongo::Configs::FlexibleContent::DEFAULT_BREAKPOINT %>
|
5
|
+
<%=
|
6
|
+
form.input(
|
7
|
+
"width_#{b}",
|
8
|
+
as: :select,
|
9
|
+
collection: options_for_column_widths,
|
10
|
+
include_blank: false,
|
11
|
+
label: t('simple_form.labels.defaults.width'),
|
12
|
+
wrapper_html: { data: { default_breakpoint: true }}
|
13
|
+
)
|
14
|
+
%>
|
15
|
+
|
16
|
+
<%= link_to icon(:cog, t('b.advanced')), '#', data: { show_all_breakpoints: true } %>
|
17
|
+
|
18
|
+
<% else %>
|
19
|
+
<%=
|
20
|
+
form.input(
|
21
|
+
"width_#{b}",
|
22
|
+
as: :select,
|
23
|
+
collection: options_for_column_widths,
|
24
|
+
include_blank: false,
|
25
|
+
wrapper_html: { style: 'display: none;', data: { advanced_breakpoint: true, "breakpoint_#{b}": true }}
|
26
|
+
)
|
27
|
+
%>
|
28
|
+
<% end %>
|
11
29
|
<% end %>
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<%= render 'backend/general_form_error', object: @column %>
|
2
2
|
|
3
3
|
<%= simple_form_for(@column, url: backend_content_row_column_path(@row, @column)) do |f| %>
|
4
|
+
<%= render 'column_width_explanation' %>
|
5
|
+
|
4
6
|
<div class="card">
|
5
7
|
<div class="card-header">
|
6
8
|
<%= t 'b.msg.flexible_content.edit_column' %>
|
@@ -1,6 +1,8 @@
|
|
1
1
|
<%= render 'backend/general_form_error', object: @column %>
|
2
2
|
|
3
3
|
<%= simple_form_for(@column, url: backend_content_row_columns_path(@row)) do |f| %>
|
4
|
+
<%= render 'column_width_explanation' %>
|
5
|
+
|
4
6
|
<div class="card">
|
5
7
|
<div class="card-header">
|
6
8
|
<%= t 'b.msg.flexible_content.add_column' %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<%= simple_form_for [:backend, @model] do |f| %>
|
2
|
+
<div class="card">
|
3
|
+
<div class="card-header">
|
4
|
+
<%= t 'b.msg.flexible_content.edit_video' %>
|
5
|
+
</div>
|
6
|
+
|
7
|
+
<div class="card-block">
|
8
|
+
<%= f.input :url, as: :string %>
|
9
|
+
<%= f.input :aspect_ratio, collection: ContentVideo::ASPECT_RATIOS, include_blank: false %>
|
10
|
+
</div>
|
11
|
+
</div>
|
12
|
+
|
13
|
+
<%= render 'backend/form_actions', cancel_url: content_path %>
|
14
|
+
<% end %>
|
@@ -14,7 +14,7 @@
|
|
14
14
|
<% @email_templates.each do |s| %>
|
15
15
|
<tr data-update-position="<%= update_position_backend_email_template_path(s) %>">
|
16
16
|
<td><%= s.description %></td>
|
17
|
-
<td class="text-
|
17
|
+
<td class="text-right">
|
18
18
|
<%= link_to_edit_translation [:backend, s] %>
|
19
19
|
</td>
|
20
20
|
</tr>
|
@@ -4,6 +4,10 @@
|
|
4
4
|
<%= render 'backend/breadcrumbs' %>
|
5
5
|
|
6
6
|
<% if @form.fields.any? %>
|
7
|
+
<p class="text-right">
|
8
|
+
<%= link_to icon(:plus, t('b.add')), new_backend_form_field_path(@form), class: 'btn btn-primary btn-sm' %>
|
9
|
+
</p>
|
10
|
+
|
7
11
|
<table class="table table-striped table-hover">
|
8
12
|
<thead class="thead-inverse">
|
9
13
|
<tr>
|
@@ -12,19 +16,11 @@
|
|
12
16
|
</tr>
|
13
17
|
</thead>
|
14
18
|
|
15
|
-
<tfoot>
|
16
|
-
<tr>
|
17
|
-
<td colspan="2" class="text-xs-center">
|
18
|
-
<%= link_to icon(:plus, t('b.msg.form_fields.add')), new_backend_form_field_path(@form), class: 'btn btn-primary' %>
|
19
|
-
</td>
|
20
|
-
</tr>
|
21
|
-
</tfoot>
|
22
|
-
|
23
19
|
<tbody>
|
24
20
|
<% @form.fields.each do |f| %>
|
25
21
|
<tr data-update-position="<%= update_position_backend_form_field_path(@form, f) %>">
|
26
22
|
<td><%= f.identifier %></td>
|
27
|
-
<td class="text-
|
23
|
+
<td class="text-right">
|
28
24
|
<%= link_to_edit edit_backend_form_field_path(@form, f) %>
|
29
25
|
<%= link_to_delete backend_form_field_path(@form, f) %>
|
30
26
|
</td>
|
@@ -32,13 +28,10 @@
|
|
32
28
|
<% end %>
|
33
29
|
</tbody>
|
34
30
|
</table>
|
31
|
+
|
35
32
|
<% else %>
|
36
|
-
<
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
<p>
|
41
|
-
<%= link_to t('b.msg.form_fields.add_first'), new_backend_form_field_path(@form), class: 'btn btn-primary' %>
|
42
|
-
</p>
|
43
|
-
</div>
|
33
|
+
<p><%= t('b.msg.form_fields.explanation') %></p>
|
34
|
+
<p>
|
35
|
+
<%= link_to t('b.msg.form_fields.add_first'), new_backend_form_field_path(@form), class: 'btn btn-primary' %>
|
36
|
+
</p>
|
44
37
|
<% end %>
|