Commit 084b93c03109b872336bb4476d1a18051b7bee15

Authored by Leandro Nunes dos Santos
2 parents 0d7f7927 4eb56579

Merge branch 'next_colivre' into ActionItem2892

Showing 41 changed files with 1657 additions and 113 deletions   Show diff stats
app/controllers/my_profile/cms_controller.rb
@@ -144,10 +144,15 @@ class CmsController < MyProfileController @@ -144,10 +144,15 @@ class CmsController < MyProfileController
144 144
145 post_only :set_home_page 145 post_only :set_home_page
146 def set_home_page 146 def set_home_page
147 - @article = profile.articles.find(params[:id])  
148 - profile.home_page = @article  
149 - profile.save(false)  
150 - session[:notice] = _('"%s" configured as home page.') % @article.name 147 + article = params[:id].nil? ? nil : profile.articles.find(params[:id])
  148 + profile.update_attribute(:home_page, article)
  149 +
  150 + if article.nil?
  151 + session[:notice] = _('Homepage reseted.')
  152 + else
  153 + session[:notice] = _('"%s" configured as homepage.') % article.name
  154 + end
  155 +
151 redirect_to (request.referer || profile.url) 156 redirect_to (request.referer || profile.url)
152 end 157 end
153 158
app/controllers/public/profile_controller.rb
@@ -206,10 +206,50 @@ class ProfileController < PublicController @@ -206,10 +206,50 @@ class ProfileController < PublicController
206 end 206 end
207 207
208 def view_more_network_activities 208 def view_more_network_activities
209 - @activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page]) 209 + @activities = @profile.tracked_notifications.paginate(:per_page => 10, :page => params[:page])
210 render :partial => 'profile_network_activities', :locals => {:network_activities => @activities} 210 render :partial => 'profile_network_activities', :locals => {:network_activities => @activities}
211 end 211 end
212 212
  213 + def more_comments
  214 + activity = ActionTracker::Record.find(:first, :conditions => {:id => params[:activity], :user_id => @profile})
  215 + comments_count = activity.comments.count
  216 + comment_page = (params[:comment_page] || 1).to_i
  217 + comments_per_page = 5
  218 + no_more_pages = comments_count <= comment_page * comments_per_page
  219 +
  220 + render :update do |page|
  221 + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
  222 + :partial => 'comment', :collection => activity.comments.paginate(:per_page => comments_per_page, :page => comment_page)
  223 +
  224 + if no_more_pages
  225 + page.remove 'profile-wall-activities-comments-more-'+params[:activity]
  226 + else
  227 + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
  228 + :partial => 'more_comments', :locals => {:activity => activity, :comment_page => comment_page}
  229 + end
  230 + end
  231 + end
  232 +
  233 + def more_replies
  234 + activity = Scrap.find(:first, :conditions => {:id => params[:activity], :receiver_id => @profile, :scrap_id => nil})
  235 + comments_count = activity.replies.count
  236 + comment_page = (params[:comment_page] || 1).to_i
  237 + comments_per_page = 5
  238 + no_more_pages = comments_count <= comment_page * comments_per_page
  239 +
  240 + render :update do |page|
  241 + page.insert_html :bottom, 'profile-wall-activities-comments-'+params[:activity],
  242 + :partial => 'profile_scrap', :collection => activity.replies.paginate(:per_page => comments_per_page, :page => comment_page), :as => :scrap
  243 +
  244 + if no_more_pages
  245 + page.remove 'profile-wall-activities-comments-more-'+params[:activity]
  246 + else
  247 + page.replace_html 'profile-wall-activities-comments-more-'+params[:activity],
  248 + :partial => 'more_replies', :locals => {:activity => activity, :comment_page => comment_page}
  249 + end
  250 + end
  251 + end
  252 +
213 def remove_scrap 253 def remove_scrap
214 begin 254 begin
215 scrap = current_user.person.scraps(params[:scrap_id]) 255 scrap = current_user.person.scraps(params[:scrap_id])
@@ -343,6 +383,7 @@ class ProfileController &lt; PublicController @@ -343,6 +383,7 @@ class ProfileController &lt; PublicController
343 end 383 end
344 end 384 end
345 385
  386 +
346 protected 387 protected
347 388
348 def check_access_to_profile 389 def check_access_to_profile
@@ -393,4 +434,5 @@ class ProfileController &lt; PublicController @@ -393,4 +434,5 @@ class ProfileController &lt; PublicController
393 def relations_to_include 434 def relations_to_include
394 [:image, :domains, :preferred_domain, :environment] 435 [:image, :domains, :preferred_domain, :environment]
395 end 436 end
  437 +
396 end 438 end
app/helpers/application_helper.rb
@@ -1424,8 +1424,8 @@ module ApplicationHelper @@ -1424,8 +1424,8 @@ module ApplicationHelper
1424 end 1424 end
1425 1425
1426 def filter_html(html, source) 1426 def filter_html(html, source)
1427 - if @plugins && source.has_macro?  
1428 - html = convert_macro(html, source) 1427 + if @plugins && source && source.has_macro?
  1428 + html = convert_macro(html, source) unless @plugins.enabled_macros.blank?
1429 #TODO This parse should be done through the macro infra, but since there 1429 #TODO This parse should be done through the macro infra, but since there
1430 # are old things that do not support it we are keeping this hot spot. 1430 # are old things that do not support it we are keeping this hot spot.
1431 html = @plugins.pipeline(:parse_content, html, source).first 1431 html = @plugins.pipeline(:parse_content, html, source).first
app/views/cms/view.rhtml
@@ -2,6 +2,18 @@ @@ -2,6 +2,18 @@
2 <%= _('Content management') %> 2 <%= _('Content management') %>
3 </h1> 3 </h1>
4 4
  5 +<% if !environment.enabled?('cant_change_homepage') && !remove_content_button(:home) %>
  6 + <div class="cms-homepage">
  7 + <%= _('Profile homepage:') %>
  8 + <% if profile.home_page %>
  9 + <%= link_to_article(profile.home_page) %>
  10 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  11 + <% else %>
  12 + <span class="cms-homepage-default"><%= _('Profile Information') %></span>
  13 + <% end %>
  14 + </div>
  15 +<% end %>
  16 +
5 <% button_bar(:style => 'margin-bottom: 1em;') do %> 17 <% button_bar(:style => 'margin-bottom: 1em;') do %>
6 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %> 18 <% parent_id = ((@article && @article.allow_children?) ? @article : nil) %>
7 19
@@ -56,7 +68,11 @@ @@ -56,7 +68,11 @@
56 <%= button_without_text :eyes, _('Public view'), article.view_url %> 68 <%= button_without_text :eyes, _('Public view'), article.view_url %>
57 <%= display_spread_button(profile, article) unless article.folder? || remove_content_button(:spread)%> 69 <%= display_spread_button(profile, article) unless article.folder? || remove_content_button(:spread)%>
58 <% if !environment.enabled?('cant_change_homepage') && !remove_content_button(:home) %> 70 <% if !environment.enabled?('cant_change_homepage') && !remove_content_button(:home) %>
59 - <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %> 71 + <% if profile.home_page != article %>
  72 + <%= expirable_button article, :home, _('Use as homepage'), { :action => 'set_home_page', :id => article.id }, :method => :post %>
  73 + <% else %>
  74 + <%= button_without_text(:'home-not', _('Reset homepage'), { :action => 'set_home_page', :id => nil }, :method => :post) %>
  75 + <% end %>
60 <% end %> 76 <% end %>
61 <%= display_delete_button(article) if !remove_content_button(:delete) %> 77 <%= display_delete_button(article) if !remove_content_button(:delete) %>
62 </td> 78 </td>
app/views/profile/_more_comments.rhtml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<div class='view-more-comments'>
  2 + <%= link_to(_('More'), :profile => @profile.identifier, :controller => 'profile', :action => 'more_comments', :activity => activity, :comment_page => (comment_page + 1)) %>
  3 +</div>
app/views/profile/_more_replies.rhtml 0 → 100644
@@ -0,0 +1,3 @@ @@ -0,0 +1,3 @@
  1 +<div class='view-more-replies'>
  2 + <%= link_to(_('More'), :profile => @profile.identifier, :controller => 'profile', :action => 'more_replies', :activity => activity, :comment_page => (comment_page + 1)) %>
  3 +</div>
app/views/profile/_profile_activities_list.rhtml
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 <% if activity.kind_of?(ActionTracker::Record) %> 4 <% if activity.kind_of?(ActionTracker::Record) %>
5 <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %> 5 <%= render :partial => 'profile_activity', :locals => { :activity => activity, :tab_action => 'wall' } if activity.visible? %>
6 <% else %> 6 <% else %>
7 - <%= render :partial => 'profile_scrap', :locals => {:scrap => activity } %> 7 + <%= render :partial => 'profile_scraps', :locals => { :activity => activity, :scrap => activity } %>
8 <% end %> 8 <% end %>
9 <% end %> 9 <% end %>
10 <% end %> 10 <% end %>
app/views/profile/_profile_comments.rhtml
1 <hr /> 1 <hr />
2 2
3 -<% if activity.comments_count > 2 %> 3 +<ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments" >
  4 +</ul>
  5 +<% if activity.comments_count > 0 %>
  6 +<div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments" >
4 <div class='view-all-comments icon-chat'> 7 <div class='view-all-comments icon-chat'>
5 - <%= link_to(_("View all %s comments") % activity.comments_count, '#') %> 8 + <%= link_to(n_('View comment', "View all %s comments", activity.comments_count) % activity.comments_count, :profile => profile.identifier, :controller => 'profile', :action => 'more_comments', :activity => activity, :comment_page => (1)) %>
6 </div> 9 </div>
  10 +</div>
7 <% end %> 11 <% end %>
8 -  
9 -<ul class="profile-wall-activities-comments" style="<%= 'display:none;' if (activity.comments_count > 2) %>" >  
10 - <%= render :partial => 'comment', :collection => activity.comments_as_thread %>  
11 -</ul>  
12 -  
13 <%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %> 12 <%= render :partial => 'profile_comment_form', :locals => { :activity => activity, :tab_action => tab_action } %>
app/views/profile/_profile_scrap.rhtml
@@ -16,13 +16,7 @@ @@ -16,13 +16,7 @@
16 </div> 16 </div>
17 </div> 17 </div>
18 18
19 - <% if scrap.replies.count > 2 %>  
20 - <div class='view-all-comments icon-chat'>  
21 - <%= link_to(_("View all %s comments") % scrap.replies.count, '#') %>  
22 - </div>  
23 - <% end %>  
24 -  
25 - <ul class="profile-wall-activities-comments scrap-replies" style="width: auto; <%= 'display:none;' if (scrap.replies.count > 2) %>" > 19 + <ul class="profile-wall-activities-comments scrap-replies" style="width: auto;" >
26 <% scrap.replies.map do |reply| %> 20 <% scrap.replies.map do |reply| %>
27 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %> 21 <%= render :partial => 'profile_scrap', :locals => {:scrap => reply} %>
28 <% end %> 22 <% end %>
app/views/profile/_profile_scraps.rhtml
1 -NÃO DEVE APARECER 1 +<li class='profile-activity-item' id='profile-activity-item-<%= scrap.id %>'>
  2 + <div class='profile-activity-image'>
  3 + <%= link_to(profile_image(scrap.sender, :minor), scrap.sender.url) %>
  4 + </div>
  5 + <div class='profile-activity-description'>
  6 + <p class='profile-activity-sender'><%= link_to scrap.sender.name, scrap.sender.url %></p>
  7 + <p class='profile-activity-text'><%= txt2html scrap.content %></p>
  8 + <p class='profile-activity-time'><%= time_ago_as_sentence(scrap.created_at) %></p>
  9 + <div class='profile-wall-actions'>
  10 + <% if logged_in? && current_person.follows?(scrap.sender) %>
  11 + <span class='profile-activity-send-reply'>
  12 + <%= link_to_function s_('profile|Comment'), "hide_and_show(['#profile-wall-message-response-#{scrap.id}'],['#profile-wall-reply-#{scrap.id}', '#profile-wall-reply-form-#{scrap.id}']);$('reply_content_#{scrap.id}').value='';$('reply_content_#{scrap.id}').focus();return false", :class => "profile-send-reply" %>
  13 + </span>
  14 + <% end %>
  15 + <%= link_to_function(_('Remove'), 'remove_item_wall(this, %s, %s, %s); return false ;' % ["'.profile-activity-item'", url_for(:profile => params[:profile], :action => :remove_scrap, :scrap_id => scrap.id, :view => params[:view]).to_json, _('Are you sure you want to remove this scrap and all its replies?').to_json]) if logged_in? && user.can_control_scrap?(scrap) %>
  16 + </div>
  17 + </div>
  18 +
  19 +
  20 + <ul id="profile-wall-activities-comments-<%= activity.id %>" class="profile-wall-activities-comments scrap-replies" style="width: auto;" >
  21 + </ul>
  22 +
  23 + <% if scrap.replies.count > 0 %>
  24 + <div id="profile-wall-activities-comments-more-<%= activity.id %>" class="profile-wall-activities-comments">
  25 + <div class='view-all-comments icon-chat'>
  26 + <%= link_to(n_('View comment', "View all %s comments", scrap.replies.count) % scrap.replies.count, :profile => profile.identifier, :controller => 'profile', :action => 'more_replies', :activity => activity, :comment_page => (1)) %>
  27 + </div>
  28 + </div>
  29 + <% end %>
  30 + <%= render :partial => 'profile_scrap_reply_form', :locals => { :scrap => scrap } %>
  31 + <hr />
  32 +</li>
plugins/comment_group/controllers/profile/comment_group_plugin_profile_controller.rb
1 class CommentGroupPluginProfileController < ProfileController 1 class CommentGroupPluginProfileController < ProfileController
2 - append_view_path File.join(File.dirname(__FILE__) + '/../views') 2 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
3 3
4 def view_comments 4 def view_comments
5 - article_id = params[:article_id]  
6 - group_id = params[:group_id] 5 + @article_id = params[:article_id]
  6 + @group_id = params[:group_id]
7 7
8 - article = profile.articles.find(article_id)  
9 - comments = article.group_comments.without_spam.in_group(group_id)  
10 - render :update do |page|  
11 - page.replace_html "comments_list_group_#{group_id}", :partial => 'comment/comment.rhtml', :collection => comments  
12 - page.replace_html "comment-count-#{group_id}", comments.count  
13 - end 8 + article = profile.articles.find(@article_id)
  9 + @group_comment_page = (params[:group_comment_page] || 1).to_i
  10 +
  11 + @comments = article.comments.without_spam.in_group(@group_id)
  12 + @comments_count = @comments.count
  13 + @comments = @comments.without_reply.paginate(:per_page => per_page, :page => @group_comment_page )
  14 +
  15 + @no_more_pages = @comments_count <= @group_comment_page * per_page
  16 + end
  17 +
  18 + def per_page
  19 + 3
14 end 20 end
15 21
16 end 22 end
plugins/comment_group/lib/comment_group_plugin.rb
@@ -24,6 +24,11 @@ class CommentGroupPlugin &lt; Noosfero::Plugin @@ -24,6 +24,11 @@ class CommentGroupPlugin &lt; Noosfero::Plugin
24 'comment_group_macro.js' 24 'comment_group_macro.js'
25 end 25 end
26 26
  27 + def stylesheet?
  28 + true
  29 + end
  30 +
  31 +
27 end 32 end
28 33
29 require_dependency 'comment_group_plugin/macros/allow_comment' 34 require_dependency 'comment_group_plugin/macros/allow_comment'
plugins/comment_group/lib/comment_group_plugin/macros/allow_comment.rb
@@ -11,7 +11,6 @@ class CommentGroupPlugin::AllowComment &lt; Noosfero::Plugin::Macro @@ -11,7 +11,6 @@ class CommentGroupPlugin::AllowComment &lt; Noosfero::Plugin::Macro
11 :css_files => 'comment_group.css' } 11 :css_files => 'comment_group.css' }
12 end 12 end
13 13
14 - #FIXME Make this test  
15 def parse(params, inner_html, source) 14 def parse(params, inner_html, source)
16 group_id = params[:group_id].to_i 15 group_id = params[:group_id].to_i
17 article = source 16 article = source
plugins/comment_group/lib/ext/article.rb
@@ -2,13 +2,10 @@ require_dependency &#39;article&#39; @@ -2,13 +2,10 @@ require_dependency &#39;article&#39;
2 2
3 class Article 3 class Article
4 4
5 - #FIXME make this test  
6 has_many :group_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'group_id IS NOT NULL'] 5 has_many :group_comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :order => 'created_at asc', :conditions => [ 'group_id IS NOT NULL']
7 6
8 - #FIXME make this test  
9 validate :not_empty_group_comments_removed 7 validate :not_empty_group_comments_removed
10 8
11 - #FIXME make this test  
12 def not_empty_group_comments_removed 9 def not_empty_group_comments_removed
13 if body 10 if body
14 groups_with_comments = group_comments.collect {|comment| comment.group_id}.uniq 11 groups_with_comments = group_comments.collect {|comment| comment.group_id}.uniq
plugins/comment_group/public/style.css 0 → 100644
@@ -0,0 +1,7 @@ @@ -0,0 +1,7 @@
  1 +div.article-comments-list-more{
  2 + width: 100%;
  3 + height: 30px;
  4 + text-align: center;
  5 + font-size: 20px;
  6 + margin-bottom: 5px;
  7 +}
plugins/comment_group/test/functional/comment_group_plugin_profile_controller_test.rb
1 -require File.dirname(__FILE__) + '/../../../../test/test_helper' 1 +require File.dirname(__FILE__) + '/../test_helper'
2 require File.dirname(__FILE__) + '/../../controllers/profile/comment_group_plugin_profile_controller' 2 require File.dirname(__FILE__) + '/../../controllers/profile/comment_group_plugin_profile_controller'
3 3
4 # Re-raise errors caught by the controller. 4 # Re-raise errors caught by the controller.
@@ -21,18 +21,52 @@ class CommentGroupPluginProfileControllerTest &lt; ActionController::TestCase @@ -21,18 +21,52 @@ class CommentGroupPluginProfileControllerTest &lt; ActionController::TestCase
21 should 'be able to show group comments' do 21 should 'be able to show group comments' do
22 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0) 22 comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
23 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0 23 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
24 - assert_template 'comment/_comment.rhtml' 24 + assert_template 'comment_group_plugin_profile/view_comments.rjs'
25 assert_match /comments_list_group_0/, @response.body 25 assert_match /comments_list_group_0/, @response.body
26 assert_match /\"comment-count-0\", \"1\"/, @response.body 26 assert_match /\"comment-count-0\", \"1\"/, @response.body
27 end 27 end
28 28
29 should 'do not show global comments' do 29 should 'do not show global comments' do
30 - comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :group_id => nil)  
31 - comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0) 30 + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'global comment', :body => 'global', :group_id => nil)
  31 + fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
32 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0 32 xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
33 - assert_template 'comment/_comment.rhtml' 33 + assert_template 'comment_group_plugin_profile/view_comments.rjs'
34 assert_match /comments_list_group_0/, @response.body 34 assert_match /comments_list_group_0/, @response.body
35 assert_match /\"comment-count-0\", \"1\"/, @response.body 35 assert_match /\"comment-count-0\", \"1\"/, @response.body
36 end 36 end
37 37
  38 + should 'show first page comments only' do
  39 + comment1 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'secondpage', :group_id => 0)
  40 + comment2 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 1', :group_id => 0)
  41 + comment3 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 2', :group_id => 0)
  42 + comment4 = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'firstpage 3', :group_id => 0)
  43 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  44 + assert_match /firstpage 1/, @response.body
  45 + assert_match /firstpage 2/, @response.body
  46 + assert_match /firstpage 3/, @response.body
  47 + assert_no_match /secondpage/, @response.body
  48 + end
  49 +
  50 + should 'show link to display more comments' do
  51 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  52 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  53 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  54 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'secondpage', :body => 'secondpage', :group_id => 0)
  55 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  56 + assert_match /group_comment_page=2/, @response.body
  57 + end
  58 +
  59 + should 'do not show link to display more comments if do not have more pages' do
  60 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  61 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  62 + comment = fast_create(Comment, :source_id => article, :author_id => profile, :title => 'a comment', :body => 'lalala', :group_id => 0)
  63 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  64 + assert_no_match /group_comment_page/, @response.body
  65 + end
  66 +
  67 + should 'do not show link to display more comments if do not have any comments' do
  68 + xhr :get, :view_comments, :profile => @profile.identifier, :article_id => article.id, :group_id => 0
  69 + assert_no_match /group_comment_page/, @response.body
  70 + end
  71 +
38 end 72 end
plugins/comment_group/test/functional/comment_group_plugin_public_controller_test.rb
1 -require File.dirname(__FILE__) + '/../../../../test/test_helper' 1 +require File.dirname(__FILE__) + '/../test_helper'
2 require File.dirname(__FILE__) + '/../../controllers/public/comment_group_plugin_public_controller' 2 require File.dirname(__FILE__) + '/../../controllers/public/comment_group_plugin_public_controller'
3 3
4 # Re-raise errors caught by the controller. 4 # Re-raise errors caught by the controller.
plugins/comment_group/test/functional/content_viewer_controller_test.rb 0 → 100644
@@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ContentViewerController
  4 + append_view_path File.join(File.dirname(__FILE__) + '/../../views')
  5 + def rescue_action(e)
  6 + raise e
  7 + end
  8 +end
  9 +
  10 +class ContentViewerControllerTest < ActionController::TestCase
  11 +
  12 + def setup
  13 + @profile = fast_create(Community)
  14 + @page = fast_create(Article, :profile_id => @profile.id, :body => "<div class=\"macro\" data-macro-group_id=\"1\" data-macro='comment_group_plugin/allow_comment' ></div>")
  15 + @environment = Environment.default
  16 + @environment.enable_plugin(CommentGroupPlugin)
  17 + end
  18 +
  19 + attr_reader :page
  20 +
  21 + should 'parse article body and render comment group view' do
  22 + comment1 = fast_create(Comment, :group_id => 1, :source_id => page.id)
  23 + get :view_page, @page.url
  24 + assert_tag 'div', :attributes => {:class => 'comment_group_1'}
  25 + assert_tag 'div', :attributes => {:id => 'comments_group_count_1'}
  26 + end
  27 +
  28 +end
plugins/comment_group/test/test_helper.rb 0 → 100644
@@ -0,0 +1 @@ @@ -0,0 +1 @@
  1 +require File.dirname(__FILE__) + '/../../../test/test_helper'
plugins/comment_group/test/unit/allow_comment_test.rb 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class AllowCommentTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + @macro = CommentGroupPlugin::AllowComment.new
  7 + end
  8 +
  9 + attr_reader :macro
  10 +
  11 + should 'have a configuration' do
  12 + assert CommentGroupPlugin::AllowComment.configuration
  13 + end
  14 +
  15 + should 'parse contents to include comment group view' do
  16 + profile = fast_create(Community)
  17 + article = fast_create(Article, :profile_id => profile.id)
  18 + comment = fast_create(Comment, :group_id => 1, :source_id => article.id)
  19 + inner_html = 'inner'
  20 + content = macro.parse({:group_id => comment.group_id}, inner_html, article)
  21 +
  22 + expects(:render).with({:partial => 'plugins/comment_group/views/comment_group.rhtml', :locals => {:group_id => comment.group_id, :article_id => article.id, :inner_html => inner_html, :count => 1, :profile_identifier => profile.identifier} })
  23 + instance_eval(&content)
  24 + end
  25 +
  26 +end
plugins/comment_group/test/unit/article_test.rb 0 → 100644
@@ -0,0 +1,31 @@ @@ -0,0 +1,31 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class ArticleTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + profile = fast_create(Community)
  7 + @article = fast_create(Article, :profile_id => profile.id)
  8 + end
  9 +
  10 + attr_reader :article
  11 +
  12 + should 'return group comments from article' do
  13 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  14 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  15 + assert_equal [comment1], article.group_comments
  16 + end
  17 +
  18 + should 'do not allow a exclusion of a group comment macro if this group has comments' do
  19 + article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=2></div>")
  20 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  21 + assert !article.save
  22 + assert_equal 'Not empty group comment cannot be removed', article.errors[:base]
  23 + end
  24 +
  25 + should 'allow save if comment group macro is not removed for group with comments' do
  26 + article.update_attribute(:body, "<div class=\"macro\" data-macro-group_id=1></div>")
  27 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  28 + assert article.save
  29 + end
  30 +
  31 +end
plugins/comment_group/test/unit/comment_group_plugin_test.rb
1 -require File.dirname(__FILE__) + '/../../../../test/test_helper' 1 +require File.dirname(__FILE__) + '/../test_helper'
2 2
3 class CommentGroupPluginTest < ActiveSupport::TestCase 3 class CommentGroupPluginTest < ActiveSupport::TestCase
4 4
5 - include Noosfero::Plugin::HotSpot  
6 -  
7 def setup 5 def setup
8 @environment = Environment.default 6 @environment = Environment.default
  7 + @plugin = CommentGroupPlugin.new
  8 + end
  9 +
  10 + attr_reader :environment, :plugin
  11 +
  12 + should 'have a name' do
  13 + assert_not_equal Noosfero::Plugin.plugin_name, CommentGroupPlugin::plugin_name
  14 + end
  15 +
  16 + should 'describe yourself' do
  17 + assert_not_equal Noosfero::Plugin.plugin_description, CommentGroupPlugin::plugin_description
  18 + end
  19 +
  20 + should 'have a js file' do
  21 + assert !plugin.js_files.blank?
9 end 22 end
10 23
11 - attr_reader :environment 24 + should 'have stylesheet' do
  25 + assert plugin.stylesheet?
  26 + end
  27 +
  28 + should 'have extra contents for comment form' do
  29 + comment = fast_create(Comment, :group_id => 1)
  30 + content = plugin.comment_form_extra_contents({:comment => comment})
  31 + expects(:hidden_field_tag).with('comment[group_id]', comment.group_id).once
  32 + instance_eval(&content)
  33 + end
  34 +
  35 + should 'do not have extra contents for comments without group' do
  36 + comment = fast_create(Comment, :group_id => nil)
  37 + content = plugin.comment_form_extra_contents({:comment => comment})
  38 + assert_equal nil, instance_eval(&content)
  39 + end
  40 +
  41 + should 'call without_group for scope passed as parameter to unavailable_comments' do
  42 + article = fast_create(Article)
  43 + article.expects(:without_group).once
  44 + plugin.unavailable_comments(article)
  45 + end
12 46
13 #FIXME Obsolete test 47 #FIXME Obsolete test
14 # 48 #
plugins/comment_group/test/unit/comment_test.rb 0 → 100644
@@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
  1 +require File.dirname(__FILE__) + '/../test_helper'
  2 +
  3 +class CommentTest < ActiveSupport::TestCase
  4 +
  5 + def setup
  6 + profile = fast_create(Community)
  7 + @article = fast_create(Article, :profile_id => profile.id)
  8 + end
  9 +
  10 + attr_reader :article
  11 +
  12 + should 'return comments that belongs to a specified group' do
  13 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  14 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  15 + comment3 = fast_create(Comment, :group_id => 2, :source_id => article.id)
  16 + assert_equal [comment1], article.comments.in_group(1)
  17 + end
  18 +
  19 + should 'return comments that do not belongs to any group' do
  20 + comment1 = fast_create(Comment, :group_id => 1, :source_id => article.id)
  21 + comment2 = fast_create(Comment, :group_id => nil, :source_id => article.id)
  22 + comment3 = fast_create(Comment, :group_id => 2, :source_id => article.id)
  23 + assert_equal [comment2], article.comments.without_group
  24 + end
  25 +
  26 +end
plugins/comment_group/views/_comment_group.rhtml
@@ -20,7 +20,13 @@ @@ -20,7 +20,13 @@
20 <div class="comment-group-loading-<%= group_id %>"/> 20 <div class="comment-group-loading-<%= group_id %>"/>
21 21
22 <div class="comments_list_toggle_group_<%= group_id %>" style="display:none"> 22 <div class="comments_list_toggle_group_<%= group_id %>" style="display:none">
23 - <div class="article-comments-list" id="comments_list_group_<%= group_id %>"></div>  
24 - <div id="page-comment-form-<%= group_id %>" class='post_comment_box closed'><%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :group_id => group_id}%></div> 23 + <div class="article-comments-list" id="comments_list_group_<%= group_id %>">
  24 + </div>
  25 + <div class ="article-comments-list-more" id="comments_list_group_<%= group_id %>_more">
  26 + </div>
  27 + <div id="page-comment-form-<%= group_id %>" class='post_comment_box closed'>
  28 + <%= render :partial => 'comment/comment_form', :locals => {:comment => Comment.new, :display_link => true, :cancel_triggers_hide => true, :group_id => group_id}%>
  29 + </div>
  30 +
25 </div> 31 </div>
26 </div> 32 </div>
plugins/comment_group/views/comment_group_plugin_profile/view_comments.rjs 0 → 100644
@@ -0,0 +1,12 @@ @@ -0,0 +1,12 @@
  1 +if @group_comment_page == 1
  2 + page.replace_html "comments_list_group_#{@group_id}", :partial => 'comment/comment.rhtml', :collection => @comments
  3 +else
  4 + page.insert_html :bottom, "comments_list_group_#{@group_id}", :partial => 'comment/comment.rhtml', :collection => @comments
  5 +end
  6 +page.replace_html "comment-count-#{@group_id}", @comments_count
  7 +
  8 +if @no_more_pages
  9 + page.replace_html "comments_list_group_#{@group_id}_more", ""
  10 +else
  11 + page.replace_html "comments_list_group_#{@group_id}_more", link_to_remote(_('More'), :url => { :profile => profile.identifier, :controller => 'comment_group_plugin_profile', :action => 'view_comments', :group_id => @group_id, :article_id => @article_id, :group_comment_page => @group_comment_page + 1}, :loaded => visual_effect(:highlight, "comments_list_group_#{@group_id}"), :method => :post, :complete => "loadCompleted(#{@group_id})")
  12 +end
plugins/community_track/lib/community_track_plugin/step.rb
@@ -7,7 +7,7 @@ class CommunityTrackPlugin::Step &lt; Folder @@ -7,7 +7,7 @@ class CommunityTrackPlugin::Step &lt; Folder
7 acts_as_list :scope => :parent 7 acts_as_list :scope => :parent
8 8
9 def belong_to_track 9 def belong_to_track
10 - errors.add(:parent, "Step not allowed at this parent.") if !parent.kind_of?(CommunityTrackPlugin::Track) 10 + errors.add(:parent, _("Step not allowed at this parent.")) unless parent.kind_of?(CommunityTrackPlugin::Track)
11 end 11 end
12 12
13 validate :belong_to_track 13 validate :belong_to_track
plugins/community_track/lib/community_track_plugin/track.rb
@@ -49,8 +49,8 @@ class CommunityTrackPlugin::Track &lt; Folder @@ -49,8 +49,8 @@ class CommunityTrackPlugin::Track &lt; Folder
49 "community-track-plugin-track" 49 "community-track-plugin-track"
50 end 50 end
51 51
52 - #FIXME make this test  
53 def first_paragraph 52 def first_paragraph
  53 + return '' if body.blank?
54 paragraphs = Hpricot(body).search('p') 54 paragraphs = Hpricot(body).search('p')
55 paragraphs.empty? ? '' : paragraphs.first.to_html 55 paragraphs.empty? ? '' : paragraphs.first.to_html
56 end 56 end
plugins/community_track/public/icons/calendar.png 0 → 100644

604 Bytes

plugins/community_track/public/style.css
@@ -193,3 +193,9 @@ @@ -193,3 +193,9 @@
193 .community-track textarea { 193 .community-track textarea {
194 width: 100%; 194 width: 100%;
195 } 195 }
  196 +
  197 +.formfield input#datepicker-from-date,
  198 +.formfield input#datepicker-to-date {
  199 + width: 115px;
  200 + background: url(/plugins/community_track/icons/calendar.png) right center no-repeat;
  201 +}
plugins/community_track/test/unit/community_track_plugin/track_test.rb
@@ -110,4 +110,18 @@ class TrackTest &lt; ActiveSupport::TestCase @@ -110,4 +110,18 @@ class TrackTest &lt; ActiveSupport::TestCase
110 assert_equal [hidden_step], @track.hidden_steps 110 assert_equal [hidden_step], @track.hidden_steps
111 end 111 end
112 112
  113 + should 'get first paragraph' do
  114 + @track.body = '<p>First</p><p>Second</p>'
  115 + assert_equal '<p>First</p>', @track.first_paragraph
  116 + end
  117 +
  118 + should 'provide first_paragraph even if body was not given' do
  119 + assert_equal '', @track.first_paragraph
  120 + end
  121 +
  122 + should 'provide first_paragraph even if body is nil' do
  123 + @track.body = nil
  124 + assert_equal '', @track.first_paragraph
  125 + end
  126 +
113 end 127 end
plugins/community_track/views/cms/community_track_plugin/_step.rhtml
@@ -4,8 +4,14 @@ @@ -4,8 +4,14 @@
4 4
5 <div> 5 <div>
6 <%= required f.text_field('name', :size => '64', :maxlength => 150) %> 6 <%= required f.text_field('name', :size => '64', :maxlength => 150) %>
7 - <%= labelled_form_field(_('Start date'), pick_date(:article, :start_date)) %>  
8 - <%= labelled_form_field(_('End date'), pick_date(:article, :end_date)) %> 7 + <%= labelled_form_field(_('Period'), (
  8 + date_range_field('article[start_date]', 'article[end_date]', @article.start_date, @article.end_date,
  9 + '%Y-%m-%d',
  10 + { :change_month => true, :change_year => true,
  11 + :date_format => 'yy-mm-dd' },
  12 + { :size => 14 })
  13 + )) %>
  14 +
9 </div> 15 </div>
10 16
11 <%= labelled_form_field check_box(:article, :hidden) + _('Hidden Step'), '' %> 17 <%= labelled_form_field check_box(:article, :hidden) + _('Hidden Step'), '' %>
public/designs/icons/tango/mod/16x16/actions/go-home-not.png 0 → 100644

1.02 KB

public/designs/icons/tango/mod/scalable/actions/go-home-not.svg 0 → 100644
@@ -0,0 +1,1112 @@ @@ -0,0 +1,1112 @@
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<svg
  3 + xmlns:osb="http://www.openswatchbook.org/uri/2009/osb"
  4 + xmlns:dc="http://purl.org/dc/elements/1.1/"
  5 + xmlns:cc="http://creativecommons.org/ns#"
  6 + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
  7 + xmlns:svg="http://www.w3.org/2000/svg"
  8 + xmlns="http://www.w3.org/2000/svg"
  9 + xmlns:xlink="http://www.w3.org/1999/xlink"
  10 + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
  11 + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
  12 + width="48"
  13 + height="48"
  14 + overflow="visible"
  15 + enable-background="new 0 0 128 129.396"
  16 + xml:space="preserve"
  17 + id="svg2"
  18 + sodipodi:version="0.32"
  19 + inkscape:version="0.48.1 r9760"
  20 + sodipodi:docname="go-home-not.svg"
  21 + version="1.0"
  22 + inkscape:export-filename="/home/85902810515/projetos/noosfero/public/designs/icons/tango/mod/16x16/actions/go-home-not.png"
  23 + inkscape:export-xdpi="30.01"
  24 + inkscape:export-ydpi="30.01"
  25 + inkscape:output_extension="org.inkscape.output.svg.inkscape"
  26 + style="display:inline;overflow:visible"><metadata
  27 + id="metadata367"><rdf:RDF><cc:Work
  28 + rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
  29 + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><cc:license
  30 + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /><dc:title></dc:title><dc:creator><cc:Agent><dc:title>Jakub Steiner</dc:title></cc:Agent></dc:creator><dc:source>http://jimmac.musichall.cz</dc:source><dc:subject><rdf:Bag><rdf:li>home</rdf:li><rdf:li>return</rdf:li><rdf:li>go</rdf:li><rdf:li>default</rdf:li><rdf:li>user</rdf:li><rdf:li>directory</rdf:li></rdf:Bag></dc:subject><dc:contributor><cc:Agent><dc:title>Tuomas Kuosmanen</dc:title></cc:Agent></dc:contributor></cc:Work><cc:License
  31 + rdf:about="http://creativecommons.org/licenses/publicdomain/"><cc:permits
  32 + rdf:resource="http://creativecommons.org/ns#Reproduction" /><cc:permits
  33 + rdf:resource="http://creativecommons.org/ns#Distribution" /><cc:permits
  34 + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /></cc:License></rdf:RDF></metadata><defs
  35 + id="defs365"><linearGradient
  36 + id="linearGradient4711"><stop
  37 + style="stop-color:#f87171;stop-opacity:1;"
  38 + offset="0"
  39 + id="stop4713" /><stop
  40 + style="stop-color:#fb1f22;stop-opacity:1;"
  41 + offset="1"
  42 + id="stop4715" /></linearGradient><linearGradient
  43 + id="linearGradient4700"><stop
  44 + style="stop-color:#b20000;stop-opacity:1;"
  45 + offset="0"
  46 + id="stop4702" /><stop
  47 + style="stop-color:#db0000;stop-opacity:1;"
  48 + offset="1"
  49 + id="stop4704" /></linearGradient><linearGradient
  50 + id="linearGradient4694"
  51 + osb:paint="solid"><stop
  52 + style="stop-color:#2042e2;stop-opacity:1;"
  53 + offset="0"
  54 + id="stop4696" /></linearGradient><inkscape:perspective
  55 + sodipodi:type="inkscape:persp3d"
  56 + inkscape:vp_x="0 : 24 : 1"
  57 + inkscape:vp_y="0 : 1000 : 0"
  58 + inkscape:vp_z="48 : 24 : 1"
  59 + inkscape:persp3d-origin="24 : 16 : 1"
  60 + id="perspective92" /><radialGradient
  61 + inkscape:collect="always"
  62 + xlink:href="#linearGradient5060"
  63 + id="radialGradient5031"
  64 + gradientUnits="userSpaceOnUse"
  65 + gradientTransform="matrix(-2.774389,0,0,1.969706,112.7623,-872.8854)"
  66 + cx="605.71429"
  67 + cy="486.64789"
  68 + fx="605.71429"
  69 + fy="486.64789"
  70 + r="117.14286" /><linearGradient
  71 + inkscape:collect="always"
  72 + id="linearGradient5060"><stop
  73 + style="stop-color:black;stop-opacity:1;"
  74 + offset="0"
  75 + id="stop5062" /><stop
  76 + style="stop-color:black;stop-opacity:0;"
  77 + offset="1"
  78 + id="stop5064" /></linearGradient><radialGradient
  79 + inkscape:collect="always"
  80 + xlink:href="#linearGradient5060"
  81 + id="radialGradient5029"
  82 + gradientUnits="userSpaceOnUse"
  83 + gradientTransform="matrix(2.774389,0,0,1.969706,-1891.633,-872.8854)"
  84 + cx="605.71429"
  85 + cy="486.64789"
  86 + fx="605.71429"
  87 + fy="486.64789"
  88 + r="117.14286" /><linearGradient
  89 + id="linearGradient5048"><stop
  90 + style="stop-color:black;stop-opacity:0;"
  91 + offset="0"
  92 + id="stop5050" /><stop
  93 + id="stop5056"
  94 + offset="0.5"
  95 + style="stop-color:black;stop-opacity:1;" /><stop
  96 + style="stop-color:black;stop-opacity:0;"
  97 + offset="1"
  98 + id="stop5052" /></linearGradient><linearGradient
  99 + inkscape:collect="always"
  100 + xlink:href="#linearGradient5048"
  101 + id="linearGradient5027"
  102 + gradientUnits="userSpaceOnUse"
  103 + gradientTransform="matrix(2.774389,0,0,1.969706,-1892.179,-872.8854)"
  104 + x1="302.85715"
  105 + y1="366.64789"
  106 + x2="302.85715"
  107 + y2="609.50507" /><linearGradient
  108 + id="linearGradient2406"><stop
  109 + style="stop-color:#7c7e79;stop-opacity:1;"
  110 + offset="0"
  111 + id="stop2408" /><stop
  112 + id="stop2414"
  113 + offset="0.1724138"
  114 + style="stop-color:#848681;stop-opacity:1;" /><stop
  115 + style="stop-color:#898c86;stop-opacity:1;"
  116 + offset="1"
  117 + id="stop2410" /></linearGradient><linearGradient
  118 + inkscape:collect="always"
  119 + id="linearGradient2390"><stop
  120 + style="stop-color:#919191;stop-opacity:1;"
  121 + offset="0"
  122 + id="stop2392" /><stop
  123 + style="stop-color:#919191;stop-opacity:0;"
  124 + offset="1"
  125 + id="stop2394" /></linearGradient><linearGradient
  126 + inkscape:collect="always"
  127 + id="linearGradient2378"><stop
  128 + style="stop-color:#575757;stop-opacity:1;"
  129 + offset="0"
  130 + id="stop2380" /><stop
  131 + style="stop-color:#575757;stop-opacity:0;"
  132 + offset="1"
  133 + id="stop2382" /></linearGradient><linearGradient
  134 + inkscape:collect="always"
  135 + id="linearGradient2368"><stop
  136 + style="stop-color:#ffffff;stop-opacity:1;"
  137 + offset="0"
  138 + id="stop2370" /><stop
  139 + style="stop-color:#ffffff;stop-opacity:0;"
  140 + offset="1"
  141 + id="stop2372" /></linearGradient><linearGradient
  142 + inkscape:collect="always"
  143 + id="linearGradient2349"><stop
  144 + style="stop-color:#000000;stop-opacity:1;"
  145 + offset="0"
  146 + id="stop2351" /><stop
  147 + style="stop-color:#000000;stop-opacity:0;"
  148 + offset="1"
  149 + id="stop2353" /></linearGradient><linearGradient
  150 + id="linearGradient2341"><stop
  151 + id="stop2343"
  152 + offset="0"
  153 + style="stop-color:#000000;stop-opacity:1;" /><stop
  154 + id="stop2345"
  155 + offset="1"
  156 + style="stop-color:#000000;stop-opacity:0;" /></linearGradient><linearGradient
  157 + id="linearGradient2329"><stop
  158 + style="stop-color:#000000;stop-opacity:0.18556701;"
  159 + offset="0"
  160 + id="stop2331" /><stop
  161 + style="stop-color:#ffffff;stop-opacity:1;"
  162 + offset="1"
  163 + id="stop2333" /></linearGradient><linearGradient
  164 + inkscape:collect="always"
  165 + id="linearGradient2319"><stop
  166 + style="stop-color:#000000;stop-opacity:1;"
  167 + offset="0"
  168 + id="stop2321" /><stop
  169 + style="stop-color:#000000;stop-opacity:0;"
  170 + offset="1"
  171 + id="stop2323" /></linearGradient><linearGradient
  172 + id="linearGradient2307"><stop
  173 + style="stop-color:#edd400;stop-opacity:1;"
  174 + offset="0"
  175 + id="stop2309" /><stop
  176 + style="stop-color:#998800;stop-opacity:1;"
  177 + offset="1"
  178 + id="stop2311" /></linearGradient><linearGradient
  179 + inkscape:collect="always"
  180 + id="linearGradient2299"><stop
  181 + style="stop-color:#ffffff;stop-opacity:1;"
  182 + offset="0"
  183 + id="stop2301" /><stop
  184 + style="stop-color:#ffffff;stop-opacity:0;"
  185 + offset="1"
  186 + id="stop2303" /></linearGradient><linearGradient
  187 + id="XMLID_2_"
  188 + gradientUnits="userSpaceOnUse"
  189 + x1="80.223602"
  190 + y1="117.5205"
  191 + x2="48.046001"
  192 + y2="59.7995"
  193 + gradientTransform="matrix(0.314683,0,0,0.314683,4.128264,3.742874)">
  194 + <stop
  195 + offset="0"
  196 + style="stop-color:#CCCCCC"
  197 + id="stop17" />
  198 + <stop
  199 + offset="0.9831"
  200 + style="stop-color:#FFFFFF"
  201 + id="stop19" />
  202 + <midPointStop
  203 + offset="0"
  204 + style="stop-color:#CCCCCC"
  205 + id="midPointStop48" />
  206 + <midPointStop
  207 + offset="0.5"
  208 + style="stop-color:#CCCCCC"
  209 + id="midPointStop50" />
  210 + <midPointStop
  211 + offset="0.9831"
  212 + style="stop-color:#FFFFFF"
  213 + id="midPointStop52" />
  214 + </linearGradient><linearGradient
  215 + inkscape:collect="always"
  216 + xlink:href="#XMLID_2_"
  217 + id="linearGradient1514"
  218 + gradientUnits="userSpaceOnUse"
  219 + gradientTransform="matrix(0.336922,0,0,0.166888,17.98288,15.46151)"
  220 + x1="52.006104"
  221 + y1="166.1331"
  222 + x2="14.049017"
  223 + y2="-42.218513" /><linearGradient
  224 + id="XMLID_39_"
  225 + gradientUnits="userSpaceOnUse"
  226 + x1="64.387703"
  227 + y1="65.124001"
  228 + x2="64.387703"
  229 + y2="35.569"
  230 + gradientTransform="matrix(0.354101,0,0,0.354101,1.638679,-0.08364921)">
  231 + <stop
  232 + offset="0"
  233 + style="stop-color:#FFFFFF"
  234 + id="stop336" />
  235 + <stop
  236 + offset="0.8539"
  237 + style="stop-color:#FF6200"
  238 + id="stop338" />
  239 + <stop
  240 + offset="1"
  241 + style="stop-color:#F25D00"
  242 + id="stop340" />
  243 + <midPointStop
  244 + offset="0"
  245 + style="stop-color:#FFFFFF"
  246 + id="midPointStop335" />
  247 + <midPointStop
  248 + offset="0.5"
  249 + style="stop-color:#FFFFFF"
  250 + id="midPointStop337" />
  251 + <midPointStop
  252 + offset="0.8539"
  253 + style="stop-color:#FF6200"
  254 + id="midPointStop339" />
  255 + <midPointStop
  256 + offset="0.5"
  257 + style="stop-color:#FF6200"
  258 + id="midPointStop341" />
  259 + <midPointStop
  260 + offset="1"
  261 + style="stop-color:#F25D00"
  262 + id="midPointStop343" />
  263 + </linearGradient><radialGradient
  264 + inkscape:collect="always"
  265 + xlink:href="#linearGradient2299"
  266 + id="radialGradient2305"
  267 + cx="7.5326638"
  268 + cy="24.202574"
  269 + fx="7.5326638"
  270 + fy="24.202574"
  271 + r="8.2452126"
  272 + gradientTransform="matrix(4.100086,0,0,4.201322,-25.41506,-78.53967)"
  273 + gradientUnits="userSpaceOnUse" /><radialGradient
  274 + inkscape:collect="always"
  275 + xlink:href="#linearGradient2307"
  276 + id="radialGradient2313"
  277 + cx="19.985598"
  278 + cy="36.77816"
  279 + fx="19.985598"
  280 + fy="36.77816"
  281 + r="1.0821035"
  282 + gradientTransform="matrix(1.125263,0,0,0.982744,-3.428678,0.565787)"
  283 + gradientUnits="userSpaceOnUse" /><radialGradient
  284 + inkscape:collect="always"
  285 + xlink:href="#linearGradient2319"
  286 + id="radialGradient2325"
  287 + cx="20.443665"
  288 + cy="37.425831"
  289 + fx="20.443665"
  290 + fy="37.425831"
  291 + r="1.0821035"
  292 + gradientTransform="matrix(1.125263,0,0,0.982744,-3.428678,0.731106)"
  293 + gradientUnits="userSpaceOnUse" /><linearGradient
  294 + inkscape:collect="always"
  295 + xlink:href="#linearGradient2329"
  296 + id="linearGradient2335"
  297 + x1="17.602522"
  298 + y1="26.057423"
  299 + x2="17.682528"
  300 + y2="32.654099"
  301 + gradientUnits="userSpaceOnUse"
  302 + gradientTransform="matrix(0.898789,0,0,1.071914,0.478025,-2.080838)" /><radialGradient
  303 + inkscape:collect="always"
  304 + xlink:href="#linearGradient2341"
  305 + id="radialGradient2339"
  306 + gradientUnits="userSpaceOnUse"
  307 + gradientTransform="matrix(4.100086,0,0,-4.201322,-5.198109,105.3535)"
  308 + cx="11.68129"
  309 + cy="19.554111"
  310 + fx="11.68129"
  311 + fy="19.554111"
  312 + r="8.2452126" /><radialGradient
  313 + inkscape:collect="always"
  314 + xlink:href="#linearGradient2349"
  315 + id="radialGradient2355"
  316 + cx="24.023088"
  317 + cy="40.56913"
  318 + fx="24.023088"
  319 + fy="40.56913"
  320 + r="16.28684"
  321 + gradientTransform="matrix(1,0,0,0.43125,0,23.07369)"
  322 + gradientUnits="userSpaceOnUse" /><radialGradient
  323 + inkscape:collect="always"
  324 + xlink:href="#linearGradient2368"
  325 + id="radialGradient2374"
  326 + cx="29.913452"
  327 + cy="30.442923"
  328 + fx="29.913452"
  329 + fy="30.442923"
  330 + r="4.001883"
  331 + gradientTransform="matrix(3.751495,0,0,3.147818,-82.00907,-65.70704)"
  332 + gradientUnits="userSpaceOnUse" /><radialGradient
  333 + inkscape:collect="always"
  334 + xlink:href="#linearGradient2378"
  335 + id="radialGradient2384"
  336 + cx="24.195112"
  337 + cy="10.577631"
  338 + fx="24.195112"
  339 + fy="10.577631"
  340 + r="15.242914"
  341 + gradientTransform="matrix(1.125263,-3.585417e-8,4.269819e-8,1.340059,-3.006704,1.355395)"
  342 + gradientUnits="userSpaceOnUse" /><linearGradient
  343 + inkscape:collect="always"
  344 + xlink:href="#linearGradient2390"
  345 + id="linearGradient2396"
  346 + x1="30.603519"
  347 + y1="37.337803"
  348 + x2="30.603519"
  349 + y2="36.112415"
  350 + gradientUnits="userSpaceOnUse"
  351 + gradientTransform="matrix(1.263867,0,0,0.859794,-6.499556,8.390924)" /><linearGradient
  352 + inkscape:collect="always"
  353 + xlink:href="#linearGradient2406"
  354 + id="linearGradient2412"
  355 + x1="17.850183"
  356 + y1="28.939463"
  357 + x2="19.040216"
  358 + y2="41.03223"
  359 + gradientUnits="userSpaceOnUse"
  360 + gradientTransform="matrix(0.888785,0,0,1.08932,2.41099,-1.524336)" /><radialGradient
  361 + inkscape:collect="always"
  362 + xlink:href="#linearGradient9647"
  363 + id="radialGradient2239"
  364 + cx="24.30225"
  365 + cy="33.30225"
  366 + fx="24.30225"
  367 + fy="33.30225"
  368 + r="12.30225"
  369 + gradientUnits="userSpaceOnUse"
  370 + gradientTransform="matrix(1.693981,0,0,1.693981,-16.86529,-25.11111)" /><linearGradient
  371 + id="linearGradient9647"><stop
  372 + style="stop-color:#ffffff;stop-opacity:1;"
  373 + offset="0"
  374 + id="stop9649" /><stop
  375 + style="stop-color:#dbdbdb;stop-opacity:1;"
  376 + offset="1"
  377 + id="stop9651" /></linearGradient><linearGradient
  378 + inkscape:collect="always"
  379 + xlink:href="#linearGradient2256"
  380 + id="linearGradient2262"
  381 + x1="21.75"
  382 + y1="15.80225"
  383 + x2="24.30225"
  384 + y2="35.05225"
  385 + gradientUnits="userSpaceOnUse"
  386 + gradientTransform="translate(0,-2)" /><linearGradient
  387 + id="linearGradient2256"><stop
  388 + style="stop-color:#ff0202;stop-opacity:1;"
  389 + offset="0"
  390 + id="stop2258" /><stop
  391 + style="stop-color:#ff9b9b;stop-opacity:1;"
  392 + offset="1"
  393 + id="stop2260" /></linearGradient><radialGradient
  394 + r="12.30225"
  395 + fy="33.30225"
  396 + fx="24.30225"
  397 + cy="33.30225"
  398 + cx="24.30225"
  399 + gradientTransform="matrix(1.693981,0,0,1.693981,-5.6354248,-11.964506)"
  400 + gradientUnits="userSpaceOnUse"
  401 + id="radialGradient3047"
  402 + xlink:href="#linearGradient9647"
  403 + inkscape:collect="always" /><linearGradient
  404 + y2="35.05225"
  405 + x2="24.30225"
  406 + y1="15.80225"
  407 + x1="21.75"
  408 + gradientTransform="translate(11.229865,11.146604)"
  409 + gradientUnits="userSpaceOnUse"
  410 + id="linearGradient3049"
  411 + xlink:href="#linearGradient2256"
  412 + inkscape:collect="always" /><radialGradient
  413 + inkscape:collect="always"
  414 + xlink:href="#linearGradient21644"
  415 + id="radialGradient21650"
  416 + cx="25.125"
  417 + cy="36.75"
  418 + fx="25.125"
  419 + fy="36.75"
  420 + r="15.75"
  421 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  422 + gradientUnits="userSpaceOnUse" /><linearGradient
  423 + inkscape:collect="always"
  424 + id="linearGradient21644"><stop
  425 + style="stop-color:#000000;stop-opacity:1;"
  426 + offset="0"
  427 + id="stop21646" /><stop
  428 + style="stop-color:#000000;stop-opacity:0;"
  429 + offset="1"
  430 + id="stop21648" /></linearGradient><linearGradient
  431 + inkscape:collect="always"
  432 + xlink:href="#linearGradient4981"
  433 + id="linearGradient4987"
  434 + x1="23.995985"
  435 + y1="20.105337"
  436 + x2="41.047836"
  437 + y2="37.959785"
  438 + gradientUnits="userSpaceOnUse"
  439 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  440 + id="linearGradient4981"><stop
  441 + style="stop-color:#cc0000;stop-opacity:1;"
  442 + offset="0"
  443 + id="stop4983" /><stop
  444 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  445 + offset="1.0000000"
  446 + id="stop4985" /></linearGradient><linearGradient
  447 + inkscape:collect="always"
  448 + xlink:href="#linearGradient11780"
  449 + id="linearGradient2057"
  450 + x1="15.737001"
  451 + y1="12.5036"
  452 + x2="53.570126"
  453 + y2="47.374317"
  454 + gradientUnits="userSpaceOnUse"
  455 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  456 + id="linearGradient11780"><stop
  457 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  458 + offset="0.0000000"
  459 + id="stop11782" /><stop
  460 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  461 + offset="1.0000000"
  462 + id="stop11784" /></linearGradient><radialGradient
  463 + inkscape:collect="always"
  464 + xlink:href="#linearGradient2248"
  465 + id="radialGradient2254"
  466 + cx="16.75"
  467 + cy="10.666344"
  468 + fx="16.75"
  469 + fy="10.666344"
  470 + r="21.25"
  471 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  472 + gradientUnits="userSpaceOnUse" /><linearGradient
  473 + inkscape:collect="always"
  474 + id="linearGradient2248"><stop
  475 + style="stop-color:#ffffff;stop-opacity:1;"
  476 + offset="0"
  477 + id="stop2250" /><stop
  478 + style="stop-color:#ffffff;stop-opacity:0;"
  479 + offset="1"
  480 + id="stop2252" /></linearGradient><radialGradient
  481 + inkscape:collect="always"
  482 + xlink:href="#linearGradient9647-3"
  483 + id="radialGradient2239-7"
  484 + cx="24.30225"
  485 + cy="33.30225"
  486 + fx="24.30225"
  487 + fy="33.30225"
  488 + r="12.30225"
  489 + gradientUnits="userSpaceOnUse"
  490 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)" /><linearGradient
  491 + id="linearGradient9647-3"><stop
  492 + style="stop-color:#ffffff;stop-opacity:1;"
  493 + offset="0"
  494 + id="stop9649-3" /><stop
  495 + style="stop-color:#dbdbdb;stop-opacity:1;"
  496 + offset="1"
  497 + id="stop9651-2" /></linearGradient><linearGradient
  498 + inkscape:collect="always"
  499 + xlink:href="#linearGradient2256-0"
  500 + id="linearGradient2262-5"
  501 + x1="21.75"
  502 + y1="15.80225"
  503 + x2="24.30225"
  504 + y2="35.05225"
  505 + gradientUnits="userSpaceOnUse"
  506 + gradientTransform="translate(23.026616,19.550612)" /><linearGradient
  507 + id="linearGradient2256-0"><stop
  508 + style="stop-color:#ff0202;stop-opacity:1;"
  509 + offset="0"
  510 + id="stop2258-2" /><stop
  511 + style="stop-color:#ff9b9b;stop-opacity:1;"
  512 + offset="1"
  513 + id="stop2260-8" /></linearGradient><radialGradient
  514 + r="15.75"
  515 + fy="36.75"
  516 + fx="25.125"
  517 + cy="36.75"
  518 + cx="25.125"
  519 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  520 + gradientUnits="userSpaceOnUse"
  521 + id="radialGradient3090"
  522 + xlink:href="#linearGradient21644"
  523 + inkscape:collect="always" /><radialGradient
  524 + inkscape:collect="always"
  525 + xlink:href="#linearGradient21644"
  526 + id="radialGradient3205"
  527 + gradientUnits="userSpaceOnUse"
  528 + gradientTransform="matrix(1,0,0,0.595238,0,14.875)"
  529 + cx="25.125"
  530 + cy="36.75"
  531 + fx="25.125"
  532 + fy="36.75"
  533 + r="15.75" /><linearGradient
  534 + inkscape:collect="always"
  535 + xlink:href="#linearGradient4981"
  536 + id="linearGradient3207"
  537 + gradientUnits="userSpaceOnUse"
  538 + gradientTransform="translate(23.026616,19.550612)"
  539 + x1="23.995985"
  540 + y1="20.105337"
  541 + x2="41.047836"
  542 + y2="37.959785" /><linearGradient
  543 + inkscape:collect="always"
  544 + xlink:href="#linearGradient11780"
  545 + id="linearGradient3209"
  546 + gradientUnits="userSpaceOnUse"
  547 + gradientTransform="translate(23.026616,19.550612)"
  548 + x1="15.737001"
  549 + y1="12.5036"
  550 + x2="53.570126"
  551 + y2="47.374317" /><radialGradient
  552 + inkscape:collect="always"
  553 + xlink:href="#linearGradient2248"
  554 + id="radialGradient3211"
  555 + gradientUnits="userSpaceOnUse"
  556 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  557 + cx="16.75"
  558 + cy="10.666344"
  559 + fx="16.75"
  560 + fy="10.666344"
  561 + r="21.25" /><radialGradient
  562 + inkscape:collect="always"
  563 + xlink:href="#linearGradient9647-3"
  564 + id="radialGradient3213"
  565 + gradientUnits="userSpaceOnUse"
  566 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  567 + cx="24.30225"
  568 + cy="33.30225"
  569 + fx="24.30225"
  570 + fy="33.30225"
  571 + r="12.30225" /><linearGradient
  572 + inkscape:collect="always"
  573 + xlink:href="#linearGradient2256-0"
  574 + id="linearGradient3215"
  575 + gradientUnits="userSpaceOnUse"
  576 + gradientTransform="translate(23.026616,19.550612)"
  577 + x1="21.75"
  578 + y1="15.80225"
  579 + x2="24.30225"
  580 + y2="35.05225" /><radialGradient
  581 + inkscape:collect="always"
  582 + xlink:href="#linearGradient21644"
  583 + id="radialGradient3218"
  584 + gradientUnits="userSpaceOnUse"
  585 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  586 + cx="25.125"
  587 + cy="36.75"
  588 + fx="25.125"
  589 + fy="36.75"
  590 + r="15.75" /><linearGradient
  591 + inkscape:collect="always"
  592 + xlink:href="#linearGradient4981"
  593 + id="linearGradient3221"
  594 + gradientUnits="userSpaceOnUse"
  595 + gradientTransform="translate(23.026616,19.550612)"
  596 + x1="23.995985"
  597 + y1="20.105337"
  598 + x2="41.047836"
  599 + y2="37.959785" /><linearGradient
  600 + inkscape:collect="always"
  601 + xlink:href="#linearGradient11780"
  602 + id="linearGradient3224"
  603 + gradientUnits="userSpaceOnUse"
  604 + gradientTransform="translate(23.026616,19.550612)"
  605 + x1="15.737001"
  606 + y1="12.5036"
  607 + x2="53.570126"
  608 + y2="47.374317" /><radialGradient
  609 + inkscape:collect="always"
  610 + xlink:href="#linearGradient2248"
  611 + id="radialGradient3227"
  612 + gradientUnits="userSpaceOnUse"
  613 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  614 + cx="16.75"
  615 + cy="10.666344"
  616 + fx="16.75"
  617 + fy="10.666344"
  618 + r="21.25" /><radialGradient
  619 + inkscape:collect="always"
  620 + xlink:href="#linearGradient9647-3"
  621 + id="radialGradient3230"
  622 + gradientUnits="userSpaceOnUse"
  623 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  624 + cx="24.30225"
  625 + cy="33.30225"
  626 + fx="24.30225"
  627 + fy="33.30225"
  628 + r="12.30225" /><linearGradient
  629 + inkscape:collect="always"
  630 + xlink:href="#linearGradient2256-0"
  631 + id="linearGradient3232"
  632 + gradientUnits="userSpaceOnUse"
  633 + gradientTransform="translate(23.026616,19.550612)"
  634 + x1="21.75"
  635 + y1="15.80225"
  636 + x2="24.30225"
  637 + y2="35.05225" /><radialGradient
  638 + inkscape:collect="always"
  639 + xlink:href="#linearGradient21644-3"
  640 + id="radialGradient3218-2"
  641 + gradientUnits="userSpaceOnUse"
  642 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  643 + cx="25.125"
  644 + cy="36.75"
  645 + fx="25.125"
  646 + fy="36.75"
  647 + r="15.75" /><linearGradient
  648 + inkscape:collect="always"
  649 + id="linearGradient21644-3"><stop
  650 + style="stop-color:#000000;stop-opacity:1;"
  651 + offset="0"
  652 + id="stop21646-9" /><stop
  653 + style="stop-color:#000000;stop-opacity:0;"
  654 + offset="1"
  655 + id="stop21648-9" /></linearGradient><linearGradient
  656 + inkscape:collect="always"
  657 + xlink:href="#linearGradient4981-1"
  658 + id="linearGradient3221-9"
  659 + gradientUnits="userSpaceOnUse"
  660 + gradientTransform="translate(23.026616,19.550612)"
  661 + x1="23.995985"
  662 + y1="20.105337"
  663 + x2="41.047836"
  664 + y2="37.959785" /><linearGradient
  665 + id="linearGradient4981-1"><stop
  666 + style="stop-color:#cc0000;stop-opacity:1;"
  667 + offset="0"
  668 + id="stop4983-4" /><stop
  669 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  670 + offset="1.0000000"
  671 + id="stop4985-7" /></linearGradient><linearGradient
  672 + inkscape:collect="always"
  673 + xlink:href="#linearGradient11780-3"
  674 + id="linearGradient3224-7"
  675 + gradientUnits="userSpaceOnUse"
  676 + gradientTransform="translate(23.026616,19.550612)"
  677 + x1="15.737001"
  678 + y1="12.5036"
  679 + x2="53.570126"
  680 + y2="47.374317" /><linearGradient
  681 + id="linearGradient11780-3"><stop
  682 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  683 + offset="0.0000000"
  684 + id="stop11782-9" /><stop
  685 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  686 + offset="1.0000000"
  687 + id="stop11784-6" /></linearGradient><radialGradient
  688 + inkscape:collect="always"
  689 + xlink:href="#linearGradient2248-9"
  690 + id="radialGradient3227-6"
  691 + gradientUnits="userSpaceOnUse"
  692 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  693 + cx="16.75"
  694 + cy="10.666344"
  695 + fx="16.75"
  696 + fy="10.666344"
  697 + r="21.25" /><linearGradient
  698 + inkscape:collect="always"
  699 + id="linearGradient2248-9"><stop
  700 + style="stop-color:#ffffff;stop-opacity:1;"
  701 + offset="0"
  702 + id="stop2250-3" /><stop
  703 + style="stop-color:#ffffff;stop-opacity:0;"
  704 + offset="1"
  705 + id="stop2252-5" /></linearGradient><radialGradient
  706 + inkscape:collect="always"
  707 + xlink:href="#linearGradient9647-3-4"
  708 + id="radialGradient3230-9"
  709 + gradientUnits="userSpaceOnUse"
  710 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  711 + cx="24.30225"
  712 + cy="33.30225"
  713 + fx="24.30225"
  714 + fy="33.30225"
  715 + r="12.30225" /><linearGradient
  716 + id="linearGradient9647-3-4"><stop
  717 + style="stop-color:#ffffff;stop-opacity:1;"
  718 + offset="0"
  719 + id="stop9649-3-2" /><stop
  720 + style="stop-color:#dbdbdb;stop-opacity:1;"
  721 + offset="1"
  722 + id="stop9651-2-0" /></linearGradient><linearGradient
  723 + inkscape:collect="always"
  724 + xlink:href="#linearGradient2256-0-0"
  725 + id="linearGradient3232-1"
  726 + gradientUnits="userSpaceOnUse"
  727 + gradientTransform="translate(23.026616,19.550612)"
  728 + x1="21.75"
  729 + y1="15.80225"
  730 + x2="24.30225"
  731 + y2="35.05225" /><linearGradient
  732 + id="linearGradient2256-0-0"><stop
  733 + style="stop-color:#ff0202;stop-opacity:1;"
  734 + offset="0"
  735 + id="stop2258-2-7" /><stop
  736 + style="stop-color:#ff9b9b;stop-opacity:1;"
  737 + offset="1"
  738 + id="stop2260-8-0" /></linearGradient><radialGradient
  739 + r="12.30225"
  740 + fy="33.30225"
  741 + fx="24.30225"
  742 + cy="33.30225"
  743 + cx="24.30225"
  744 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  745 + gradientUnits="userSpaceOnUse"
  746 + id="radialGradient3276"
  747 + xlink:href="#linearGradient9647-3-4"
  748 + inkscape:collect="always" /><linearGradient
  749 + y2="35.05225"
  750 + x2="24.30225"
  751 + y1="15.80225"
  752 + x1="21.75"
  753 + gradientTransform="translate(23.026616,19.550612)"
  754 + gradientUnits="userSpaceOnUse"
  755 + id="linearGradient3278"
  756 + xlink:href="#linearGradient2256-0-0"
  757 + inkscape:collect="always" /><radialGradient
  758 + inkscape:collect="always"
  759 + xlink:href="#linearGradient21644-3-0"
  760 + id="radialGradient3218-2-4"
  761 + gradientUnits="userSpaceOnUse"
  762 + gradientTransform="matrix(1.173803,0,0,0.3571428,17.76075,50.050612)"
  763 + cx="25.125"
  764 + cy="36.75"
  765 + fx="25.125"
  766 + fy="36.75"
  767 + r="15.75" /><linearGradient
  768 + id="linearGradient21644-3-0"><stop
  769 + style="stop-color:#000000;stop-opacity:1;"
  770 + offset="0"
  771 + id="stop21646-9-1" /><stop
  772 + style="stop-color:#000000;stop-opacity:0;"
  773 + offset="1"
  774 + id="stop21648-9-8" /></linearGradient><linearGradient
  775 + inkscape:collect="always"
  776 + xlink:href="#linearGradient4981-1-6"
  777 + id="linearGradient3221-9-6"
  778 + gradientUnits="userSpaceOnUse"
  779 + gradientTransform="translate(23.026616,19.550612)"
  780 + x1="23.995985"
  781 + y1="20.105337"
  782 + x2="41.047836"
  783 + y2="37.959785" /><linearGradient
  784 + id="linearGradient4981-1-6"><stop
  785 + style="stop-color:#cc0000;stop-opacity:1;"
  786 + offset="0"
  787 + id="stop4983-4-0" /><stop
  788 + style="stop-color:#b30000;stop-opacity:1.0000000;"
  789 + offset="1.0000000"
  790 + id="stop4985-7-7" /></linearGradient><linearGradient
  791 + inkscape:collect="always"
  792 + xlink:href="#linearGradient11780-3-5"
  793 + id="linearGradient3224-7-4"
  794 + gradientUnits="userSpaceOnUse"
  795 + gradientTransform="translate(23.026616,19.550612)"
  796 + x1="15.737001"
  797 + y1="12.5036"
  798 + x2="53.570126"
  799 + y2="47.374317" /><linearGradient
  800 + id="linearGradient11780-3-5"><stop
  801 + style="stop-color:#ff8b8b;stop-opacity:1.0000000;"
  802 + offset="0.0000000"
  803 + id="stop11782-9-4" /><stop
  804 + style="stop-color:#ec1b1b;stop-opacity:1.0000000;"
  805 + offset="1.0000000"
  806 + id="stop11784-6-8" /></linearGradient><radialGradient
  807 + inkscape:collect="always"
  808 + xlink:href="#linearGradient2248-9-9"
  809 + id="radialGradient3227-6-4"
  810 + gradientUnits="userSpaceOnUse"
  811 + gradientTransform="matrix(4.154957,0,0,3.198723,-29.818914,-1.9585976)"
  812 + cx="16.75"
  813 + cy="10.666344"
  814 + fx="16.75"
  815 + fy="10.666344"
  816 + r="21.25" /><linearGradient
  817 + inkscape:collect="always"
  818 + id="linearGradient2248-9-9"><stop
  819 + style="stop-color:#ffffff;stop-opacity:1;"
  820 + offset="0"
  821 + id="stop2250-3-5" /><stop
  822 + style="stop-color:#ffffff;stop-opacity:0;"
  823 + offset="1"
  824 + id="stop2252-5-3" /></linearGradient><radialGradient
  825 + r="12.30225"
  826 + fy="33.30225"
  827 + fx="24.30225"
  828 + cy="33.30225"
  829 + cx="24.30225"
  830 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  831 + gradientUnits="userSpaceOnUse"
  832 + id="radialGradient3276-7"
  833 + xlink:href="#linearGradient9647-3-4-6"
  834 + inkscape:collect="always" /><linearGradient
  835 + id="linearGradient9647-3-4-6"><stop
  836 + style="stop-color:#ffffff;stop-opacity:1;"
  837 + offset="0"
  838 + id="stop9649-3-2-7" /><stop
  839 + style="stop-color:#dbdbdb;stop-opacity:1;"
  840 + offset="1"
  841 + id="stop9651-2-0-1" /></linearGradient><linearGradient
  842 + y2="35.05225"
  843 + x2="24.30225"
  844 + y1="15.80225"
  845 + x1="21.75"
  846 + gradientTransform="translate(23.026616,19.550612)"
  847 + gradientUnits="userSpaceOnUse"
  848 + id="linearGradient3278-2"
  849 + xlink:href="#linearGradient2256-0-0-1"
  850 + inkscape:collect="always" /><linearGradient
  851 + id="linearGradient2256-0-0-1"><stop
  852 + style="stop-color:#ff0202;stop-opacity:1;"
  853 + offset="0"
  854 + id="stop2258-2-7-8" /><stop
  855 + style="stop-color:#ff9b9b;stop-opacity:1;"
  856 + offset="1"
  857 + id="stop2260-8-0-4" /></linearGradient><radialGradient
  858 + r="12.30225"
  859 + fy="33.30225"
  860 + fx="24.30225"
  861 + cy="33.30225"
  862 + cx="24.30225"
  863 + gradientTransform="matrix(1.693981,0,0,1.693981,6.1613255,-3.5604976)"
  864 + gradientUnits="userSpaceOnUse"
  865 + id="radialGradient3812"
  866 + xlink:href="#linearGradient9647-3-4-6"
  867 + inkscape:collect="always" /><linearGradient
  868 + y2="35.05225"
  869 + x2="24.30225"
  870 + y1="15.80225"
  871 + x1="21.75"
  872 + gradientTransform="translate(23.026616,19.550612)"
  873 + gradientUnits="userSpaceOnUse"
  874 + id="linearGradient3814"
  875 + xlink:href="#linearGradient2256-0-0-1"
  876 + inkscape:collect="always" /><radialGradient
  877 + inkscape:collect="always"
  878 + xlink:href="#linearGradient9647-3-4-6"
  879 + id="radialGradient3886"
  880 + gradientUnits="userSpaceOnUse"
  881 + gradientTransform="matrix(0.85754753,0,0,0.85754753,16.064712,11.20392)"
  882 + cx="24.30225"
  883 + cy="33.30225"
  884 + fx="24.30225"
  885 + fy="33.30225"
  886 + r="12.30225" /><linearGradient
  887 + inkscape:collect="always"
  888 + xlink:href="#linearGradient2256-0-0-1"
  889 + id="linearGradient3888"
  890 + gradientUnits="userSpaceOnUse"
  891 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  892 + x1="21.75"
  893 + y1="15.80225"
  894 + x2="24.30225"
  895 + y2="35.05225" /><radialGradient
  896 + inkscape:collect="always"
  897 + xlink:href="#linearGradient2248-9-9"
  898 + id="radialGradient3891"
  899 + gradientUnits="userSpaceOnUse"
  900 + gradientTransform="matrix(2.1094827,0,0,1.5765366,-2.293898,12.776643)"
  901 + cx="16.75"
  902 + cy="10.666344"
  903 + fx="16.75"
  904 + fy="10.666344"
  905 + r="21.25" /><linearGradient
  906 + inkscape:collect="always"
  907 + xlink:href="#linearGradient11780-3-5"
  908 + id="linearGradient3894"
  909 + gradientUnits="userSpaceOnUse"
  910 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  911 + x1="15.737001"
  912 + y1="12.5036"
  913 + x2="53.570126"
  914 + y2="47.374317" /><linearGradient
  915 + inkscape:collect="always"
  916 + xlink:href="#linearGradient4981-1-6"
  917 + id="linearGradient3897"
  918 + gradientUnits="userSpaceOnUse"
  919 + gradientTransform="matrix(0.50623208,0,0,0.50623208,24.602463,22.903505)"
  920 + x1="23.995985"
  921 + y1="20.105337"
  922 + x2="41.047836"
  923 + y2="37.959785" /><radialGradient
  924 + inkscape:collect="always"
  925 + xlink:href="#linearGradient21644-3-0"
  926 + id="radialGradient3900"
  927 + gradientUnits="userSpaceOnUse"
  928 + gradientTransform="matrix(0.75877044,0,0,0.21650012,17.801926,37.031146)"
  929 + cx="25.125"
  930 + cy="36.75"
  931 + fx="25.125"
  932 + fy="36.75"
  933 + r="15.75" /><linearGradient
  934 + inkscape:collect="always"
  935 + xlink:href="#linearGradient4700"
  936 + id="linearGradient4706"
  937 + x1="42"
  938 + y1="40.46875"
  939 + x2="30.3125"
  940 + y2="29.09375"
  941 + gradientUnits="userSpaceOnUse" /><linearGradient
  942 + inkscape:collect="always"
  943 + xlink:href="#linearGradient4711"
  944 + id="linearGradient4717"
  945 + x1="29.3125"
  946 + y1="28.25"
  947 + x2="44.125"
  948 + y2="42.5625"
  949 + gradientUnits="userSpaceOnUse" /></defs><sodipodi:namedview
  950 + inkscape:cy="18.229536"
  951 + inkscape:cx="35.718843"
  952 + inkscape:zoom="8"
  953 + inkscape:window-height="827"
  954 + inkscape:window-width="1440"
  955 + inkscape:pageshadow="2"
  956 + inkscape:pageopacity="0.0"
  957 + borderopacity="0.21568627"
  958 + bordercolor="#666666"
  959 + pagecolor="#ffffff"
  960 + id="base"
  961 + inkscape:showpageshadow="false"
  962 + inkscape:window-x="0"
  963 + inkscape:window-y="0"
  964 + inkscape:current-layer="layer3"
  965 + fill="#555753"
  966 + showgrid="false"
  967 + stroke="#a40000"
  968 + showguides="true"
  969 + inkscape:guide-bbox="true"
  970 + inkscape:window-maximized="1" />
  971 +
  972 +<g
  973 + inkscape:groupmode="layer"
  974 + id="layer1"
  975 + inkscape:label="Home"
  976 + style="display:inline"
  977 + sodipodi:insensitive="true"><g
  978 + style="display:inline;overflow:visible"
  979 + id="g3710"><g
  980 + transform="matrix(0.02158196,0,0,0.01859457,43.12251,41.63767)"
  981 + id="g5022"
  982 + style="display:inline"><rect
  983 + style="opacity:0.40206185;color:#000000;fill:url(#linearGradient5027);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  984 + id="rect4173"
  985 + width="1339.6335"
  986 + height="478.35718"
  987 + x="-1559.2523"
  988 + y="-150.69685" /><path
  989 + inkscape:connector-curvature="0"
  990 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5029);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  991 + d="m -219.61876,-150.68038 c 0,0 0,478.33079 0,478.33079 142.874166,0.90045 345.40022,-107.16966 345.40014,-239.196175 0,-132.026537 -159.436816,-239.134595 -345.40014,-239.134615 z"
  992 + id="path5058"
  993 + sodipodi:nodetypes="cccc" /><path
  994 + inkscape:connector-curvature="0"
  995 + sodipodi:nodetypes="cccc"
  996 + id="path5018"
  997 + d="m -1559.2523,-150.68038 c 0,0 0,478.33079 0,478.33079 -142.8742,0.90045 -345.4002,-107.16966 -345.4002,-239.196175 0,-132.026537 159.4368,-239.134595 345.4002,-239.134615 z"
  998 + style="opacity:0.40206185;color:#000000;fill:url(#radialGradient5031);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /></g><path
  999 + inkscape:connector-curvature="0"
  1000 + sodipodi:nodetypes="ccccccccc"
  1001 + id="rect1512"
  1002 + d="m 21.619576,8.1833733 5.957459,0 c 0.839732,0 13.886475,15.4353277 13.886475,16.3406587 l -0.443521,18.496745 c 0,0.905333 -0.67603,1.634177 -1.515762,1.634177 l -31.4572774,0 c -0.8397329,0 -1.5157625,-0.728844 -1.5157625,-1.634177 l 0.056478,-18.496745 c 0,-0.905331 14.1921789,-16.3406587 15.0319109,-16.3406587 z"
  1003 + style="color:#000000;fill:url(#linearGradient1514);fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:1.0000006;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1004 + inkscape:connector-curvature="0"
  1005 + d="m 46.963575,45.735573 -45.3248988,0 0,-45.32489746 45.3248988,0 0,45.32489746 z"
  1006 + id="path5"
  1007 + style="fill:none" /><path
  1008 + inkscape:connector-curvature="0"
  1009 + sodipodi:nodetypes="ccccc"
  1010 + clip-rule="evenodd"
  1011 + d="m 23,29 -0.04574,15.090942 -11.842791,0 L 11,29 23,29 z"
  1012 + id="path2327"
  1013 + style="fill:url(#linearGradient2335);fill-opacity:1;fill-rule:evenodd" /><path
  1014 + inkscape:connector-curvature="0"
  1015 + style="opacity:0.3125;color:#000000;fill:none;stroke:#ffffff;stroke-width:1.00000012;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible"
  1016 + d="m 21.780459,9.405584 5.559097,0 c 0.783582,0 13.000869,14.399588 13.000869,15.244172 l -0.347158,18.212311 c 0,0.459259 -0.143737,0.653465 -0.512375,0.653465 l -31.3872026,0.01428 c -0.3686377,0 -0.5839636,-0.07992 -0.5839636,-0.45355 L 7.7250676,24.649756 c 0,-0.844584 13.2718124,-15.244172 14.0553914,-15.244172 z"
  1017 + id="path2357"
  1018 + sodipodi:nodetypes="ccccccccc" /><path
  1019 + inkscape:connector-curvature="0"
  1020 + sodipodi:nodetypes="ccccccc"
  1021 + style="opacity:0.2;fill:url(#radialGradient2384);fill-opacity:1;fill-rule:evenodd"
  1022 + id="path23"
  1023 + d="M 7.2075295,27.943053 7.1532728,30.538247 25.521437,17.358993 40.807832,28.513421 40.879142,28.201707 24.508686,12.297576 7.2075295,27.943053 z"
  1024 + clip-rule="evenodd" /><path
  1025 + inkscape:connector-curvature="0"
  1026 + sodipodi:nodetypes="ccccc"
  1027 + style="fill:url(#linearGradient2412);fill-opacity:1;fill-rule:evenodd"
  1028 + id="path188"
  1029 + d="m 22,30 0,14.090942 -9.811029,0 L 12,30 22,30 z"
  1030 + clip-rule="evenodd" /><path
  1031 + inkscape:connector-curvature="0"
  1032 + clip-rule="evenodd"
  1033 + d="m 19.576856,36.44767 c 0.67279,0 1.216616,0.474605 1.216616,1.058507 0,0.589811 -0.543826,1.068355 -1.216616,1.068355 -0.672272,0 -1.218686,-0.478544 -1.218686,-1.068355 5.15e-4,-0.583902 0.546414,-1.058507 1.218686,-1.058507 z"
  1034 + id="path2315"
  1035 + style="opacity:0.40909089;fill:url(#radialGradient2325);fill-opacity:1;fill-rule:evenodd" /><path
  1036 + inkscape:connector-curvature="0"
  1037 + style="fill:url(#radialGradient2313);fill-opacity:1;fill-rule:evenodd"
  1038 + id="path217"
  1039 + d="m 19.462314,35.932229 c 0.672789,0 1.216615,0.474605 1.216615,1.058507 0,0.589809 -0.543826,1.068353 -1.216615,1.068353 -0.672273,0 -1.218687,-0.478544 -1.218687,-1.068353 5.15e-4,-0.583902 0.546414,-1.058507 1.218687,-1.058507 z"
  1040 + clip-rule="evenodd" /><path
  1041 + inkscape:connector-curvature="0"
  1042 + sodipodi:nodetypes="ccccccccccccc"
  1043 + style="fill:url(#XMLID_39_)"
  1044 + id="path342"
  1045 + d="m 24.447748,11.559337 18.92706,17.169868 0.494679,0.391991 0.403676,-0.171385 -0.37287,-0.761673 L 43.622679,27.964702 24.447748,12.392396 5.0582327,28.135731 4.8206309,28.279851 4.603921,28.986637 5.0373408,29.115885 5.4218948,28.807462 24.447748,11.559337 z" /><path
  1046 + inkscape:connector-curvature="0"
  1047 + sodipodi:nodetypes="cccccccccc"
  1048 + d="M 24.330168,2.2713382 2.4484294,20.372675 1.8237005,27.538603 3.8236367,29.602926 c 0,0 20.4073813,-17.157285 20.6240933,-17.327963 L 44.08027,29.818223 45.978694,27.494226 44.362903,20.382852 24.44773,2.1668788 24.330168,2.2713382 z"
  1049 + id="path362"
  1050 + style="fill:#ef2929;stroke:#a40000" /><path
  1051 + inkscape:connector-curvature="0"
  1052 + sodipodi:nodetypes="ccccc"
  1053 + id="path1536"
  1054 + d="M 2.8413446,20.613129 2.5497894,27.236494 24.369219,8.980075 24.298891,3.0867443 2.8413446,20.613129 z"
  1055 + style="opacity:0.40909089;color:#000000;fill:url(#radialGradient2305);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1056 + inkscape:connector-curvature="0"
  1057 + style="opacity:0.13636367;color:#000000;fill:url(#radialGradient2339);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible"
  1058 + d="M 24.483763,8.7509884 24.583223,2.9098867 43.912186,20.56184 45.403998,27.062652 24.483763,8.7509884 z"
  1059 + id="path2337"
  1060 + sodipodi:nodetypes="ccccc" /><path
  1061 + inkscape:connector-curvature="0"
  1062 + sodipodi:nodetypes="ccccccccc"
  1063 + id="rect2361"
  1064 + d="m 27.102228,27.719824 9.039995,0 c 0.770595,0 1.390967,0.62037 1.390967,1.390967 l -0.008,9.079221 c 0,0.770596 -0.596322,1.265969 -1.366918,1.265969 l -9.056083,0 c -0.770597,0 -1.390967,-0.620373 -1.390967,-1.390969 l 0,-8.954221 c 0,-0.770597 0.62037,-1.390967 1.390967,-1.390967 z"
  1065 + style="opacity:0.31818183;color:#000000;fill:none;stroke:#ffffff;stroke-width:0.99999934;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><rect
  1066 + ry="0.38128215"
  1067 + rx="0.38128215"
  1068 + y="28.514256"
  1069 + x="26.507767"
  1070 + height="9.9624557"
  1071 + width="10.001333"
  1072 + id="rect3263"
  1073 + style="color:#000000;fill:#3465a4;fill-opacity:1;fill-rule:nonzero;stroke:#757575;stroke-width:0.9999994;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible" /><path
  1074 + inkscape:connector-curvature="0"
  1075 + sodipodi:nodetypes="ccccc"
  1076 + id="rect2363"
  1077 + d="m 27.107118,34.408261 c 3.617983,0.331177 5.527724,-1.445704 8.868152,-1.55274 L 36,29.00603 27.088388,29 l 0.01873,5.408261 z"
  1078 + style="opacity:0.39772728;color:#000000;fill:url(#radialGradient2374);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0.99999958;marker:none;visibility:visible;display:inline;overflow:visible" /></g></g><g
  1079 + inkscape:groupmode="layer"
  1080 + id="layer3"
  1081 + inkscape:label="Cancel"
  1082 + style="display:inline"
  1083 + sodipodi:insensitive="true"><path
  1084 + inkscape:connector-curvature="0"
  1085 + id="path21642-1"
  1086 + d="m 47.662816,44.987526 c -0.120652,1.646851 -3.213412,2.606775 -5.88153,3.03684 -4.362088,0.658404 -9.413,0.503003 -13.246573,-0.867841 -2.049624,-0.673315 -3.29125,-2.200566 -1.810314,-3.341428 2.178762,-1.659613 6.251742,-2.183438 9.862965,-2.236334 3.69133,-0.006 7.82464,0.471868 10.226986,2.081485 0.520681,0.38489 0.853108,0.849828 0.848466,1.327278 z"
  1087 + style="opacity:0.63068183;color:#000000;fill:url(#radialGradient3900);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible" /><rect
  1088 + style="fill:url(#linearGradient4706);fill-opacity:1;fill-rule:nonzero;stroke:#850000;stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0"
  1089 + id="rect4692"
  1090 + width="21.625"
  1091 + height="21.9375"
  1092 + x="25.9375"
  1093 + y="24.0625"
  1094 + rx="0.38128215"
  1095 + ry="0.38128215" /><rect
  1096 + style="fill:none;stroke:url(#linearGradient4717);stroke-width:0.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;display:inline;overflow:visible"
  1097 + id="rect4709"
  1098 + width="20.875"
  1099 + height="21"
  1100 + x="26.3125"
  1101 + y="24.5625"
  1102 + rx="0.38128215"
  1103 + ry="0.38128215" /><path
  1104 + style="fill:#cc2e2e;fill-opacity:0.89138579;stroke:none;display:inline;overflow:visible"
  1105 + d="m 26.4375,24.8125 20.625,0.125 L 47,39.4375 C 41.4375,36.625 39.859375,37.3125 37.195313,37.765625 35.025662,38.134656 32.65625,40.125 26.5,39.625 z"
  1106 + id="rect4720"
  1107 + inkscape:connector-curvature="0"
  1108 + sodipodi:nodetypes="cccscc" /><path
  1109 + inkscape:connector-curvature="0"
  1110 + id="path2787-5"
  1111 + d="m 33.090545,29.231406 c -0.720061,0.72006 -1.440121,1.44012 -2.160181,2.160181 1.271499,1.271499 2.542997,2.542997 3.814496,3.814497 -1.271499,1.271499 -2.542997,2.542997 -3.814496,3.814496 0.72006,0.720061 1.44012,1.440121 2.160181,2.160182 1.271499,-1.271499 2.542997,-2.542999 3.814496,-3.814498 1.271499,1.271499 2.542998,2.542999 3.814497,3.814498 0.72006,-0.720061 1.440121,-1.440121 2.160181,-2.160182 -1.271499,-1.271499 -2.542998,-2.542997 -3.814497,-3.814496 1.271499,-1.2715 2.542998,-2.542998 3.814497,-3.814497 -0.72006,-0.720061 -1.440121,-1.440121 -2.160181,-2.160181 -1.271499,1.271499 -2.542998,2.542998 -3.814497,3.814497 -1.271499,-1.271499 -2.542997,-2.542998 -3.814496,-3.814497 z"
  1112 + style="fill:url(#radialGradient3886);fill-opacity:1;fill-rule:evenodd;stroke:url(#linearGradient3888);stroke-width:0.50623184;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;display:inline;overflow:visible" /></g></svg>
0 \ No newline at end of file 1113 \ No newline at end of file
public/designs/icons/tango/style.css
1 /******************SMALL ICONS********************/ 1 /******************SMALL ICONS********************/
2 .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) } 2 .icon-edit { background-image: url(Tango/16x16/apps/text-editor.png) }
3 -.icon-home { background-image: url(Tango/16x16/actions/go-home.png) } 3 +.icon-home { background-image: url(Tango/16x16/actions/go-home.png) }
  4 +.icon-home-not { background-image: url(mod/16x16/actions/go-home-not.png) }
4 .icon-new, 5 .icon-new,
5 .icon-suggest { background-image: url(Tango/16x16/actions/filenew.png) } 6 .icon-suggest { background-image: url(Tango/16x16/actions/filenew.png) }
6 .icon-close { background-image: url(Tango/16x16/actions/gtk-cancel.png) } 7 .icon-close { background-image: url(Tango/16x16/actions/gtk-cancel.png) }
public/javascripts/application.js
@@ -853,6 +853,12 @@ Array.min = function(array) { @@ -853,6 +853,12 @@ Array.min = function(array) {
853 return Math.min.apply(Math, array); 853 return Math.min.apply(Math, array);
854 }; 854 };
855 855
  856 +function hideAndGetUrl(link) {
  857 + link.hide();
  858 + url = jQuery(link).attr('href');
  859 + jQuery.get(url);
  860 +}
  861 +
856 jQuery(function($){ 862 jQuery(function($){
857 $('.submit-with-keypress').live('keydown', function(e) { 863 $('.submit-with-keypress').live('keydown', function(e) {
858 field = this; 864 field = this;
@@ -875,12 +881,21 @@ jQuery(function($){ @@ -875,12 +881,21 @@ jQuery(function($){
875 } 881 }
876 }); 882 });
877 883
878 - $('.view-all-comments').live('click', function(e) {  
879 - var link = this;  
880 - $(link).parent().find('.profile-wall-activities-comments').show();  
881 - $(link).hide(); 884 + $('#content').delegate( '.view-all-comments a', 'click', function(e) {
  885 + hideAndGetUrl(this);
882 return false; 886 return false;
  887 + });
  888 +
  889 + $('#content').delegate('.view-more-replies a', 'click', function(e) {
  890 + hideAndGetUrl(this);
  891 + return false;
883 }); 892 });
  893 +
  894 + $('#content').delegate('.view-more-comments a', 'click', function(e) {
  895 + hideAndGetUrl(this);
  896 + return false;
  897 + });
  898 +
884 $('.focus-on-comment').live('click', function(e) { 899 $('.focus-on-comment').live('click', function(e) {
885 var link = this; 900 var link = this;
886 $(link).parents('.profile-activity-item').find('textarea').focus(); 901 $(link).parents('.profile-activity-item').find('textarea').focus();
public/stylesheets/application.css
@@ -3137,7 +3137,7 @@ table.cms-articles a.icon { @@ -3137,7 +3137,7 @@ table.cms-articles a.icon {
3137 text-overflow: ellipsis; 3137 text-overflow: ellipsis;
3138 } 3138 }
3139 3139
3140 -table.cms-articles a.icon, table.cms-articles a.icon-parent-folder { 3140 +table.cms-articles a.icon, table.cms-articles a.icon-parent-folder, .cms-homepage a.icon {
3141 padding: 0px 0px 3px 20px; 3141 padding: 0px 0px 3px 20px;
3142 background-repeat: no-repeat; 3142 background-repeat: no-repeat;
3143 } 3143 }
@@ -3156,6 +3156,14 @@ table.cms-articles .icon:hover { @@ -3156,6 +3156,14 @@ table.cms-articles .icon:hover {
3156 border-right: 1px solid #ccc; 3156 border-right: 1px solid #ccc;
3157 } 3157 }
3158 3158
  3159 +.cms-homepage a.icon {
  3160 + border: none;
  3161 +}
  3162 +
  3163 +.cms-homepage a:hover {
  3164 + background-color: transparent;
  3165 +}
  3166 +
3159 .select-article-type { 3167 .select-article-type {
3160 padding: 5px 20px; 3168 padding: 5px 20px;
3161 width: 455px; 3169 width: 455px;
@@ -5705,6 +5713,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img { @@ -5705,6 +5713,10 @@ li.profile-activity-item.upload_image .activity-gallery-images-count-1 img {
5705 padding-left: 20px; 5713 padding-left: 20px;
5706 } 5714 }
5707 5715
  5716 +.view-more-comments, .view-more-replies {
  5717 + text-align: center;
  5718 +}
  5719 +
5708 /* Profile activity relative dimensions */ 5720 /* Profile activity relative dimensions */
5709 5721
5710 #leave_scrap { 5722 #leave_scrap {
test/functional/cms_controller_test.rb
@@ -109,6 +109,18 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -109,6 +109,18 @@ class CmsControllerTest &lt; ActionController::TestCase
109 assert_no_tag :tag => 'a', :content => 'Use as homepage', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/set_home_page/#{folder.id}" } 109 assert_no_tag :tag => 'a', :content => 'Use as homepage', :attributes => { :href => "/myprofile/#{profile.identifier}/cms/set_home_page/#{folder.id}" }
110 end 110 end
111 111
  112 + should 'display the profile homepage if can change homepage' do
  113 + env = Environment.default; env.disable('cant_change_homepage')
  114 + get :index, :profile => profile.identifier
  115 + assert_tag :tag => 'div', :content => /Profile homepage/, :attributes => { :class => "cms-homepage"}
  116 + end
  117 +
  118 + should 'not display the profile homepage if cannot change homepage' do
  119 + env = Environment.default; env.enable('cant_change_homepage')
  120 + get :index, :profile => profile.identifier
  121 + assert_no_tag :tag => 'div', :content => /Profile homepage/, :attributes => { :class => "cms-homepage"}
  122 + end
  123 +
112 should 'be able to set home page' do 124 should 'be able to set home page' do
113 a = profile.articles.build(:name => 'my new home page') 125 a = profile.articles.build(:name => 'my new home page')
114 a.save! 126 a.save!
@@ -119,6 +131,7 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -119,6 +131,7 @@ class CmsControllerTest &lt; ActionController::TestCase
119 131
120 profile.reload 132 profile.reload
121 assert_equal a, profile.home_page 133 assert_equal a, profile.home_page
  134 + assert_match /configured/, session[:notice]
122 end 135 end
123 136
124 should 'be able to set home page even when profile description is invalid' do 137 should 'be able to set home page even when profile description is invalid' do
@@ -154,6 +167,37 @@ class CmsControllerTest &lt; ActionController::TestCase @@ -154,6 +167,37 @@ class CmsControllerTest &lt; ActionController::TestCase
154 assert_redirected_to profile.url 167 assert_redirected_to profile.url
155 end 168 end
156 169
  170 + should 'be able to reset home page' do
  171 + a = profile.articles.build(:name => 'my new home page')
  172 + a.save!
  173 +
  174 + profile.home_page = a
  175 + profile.save!
  176 +
  177 + post :set_home_page, :profile => profile.identifier, :id => nil
  178 +
  179 + profile.reload
  180 + assert_equal nil, profile.home_page
  181 + assert_match /reseted/, session[:notice]
  182 + end
  183 +
  184 + should 'display default home page' do
  185 + profile.home_page = nil
  186 + profile.save!
  187 + get :index, :profile => profile.identifier
  188 + assert_tag :tag => 'div', :attributes => { :class => "cms-homepage" }, :descendant => { :tag => "span", :content => /Profile Information/ }
  189 + end
  190 +
  191 + should 'display article as home page' do
  192 + a = profile.articles.build(:name => 'my new home page')
  193 + a.save!
  194 + profile.home_page = a
  195 + profile.save!
  196 + Article.stubs(:short_description).returns('short description')
  197 + get :index, :profile => profile.identifier
  198 + assert_tag :tag => 'div', :attributes => { :class => "cms-homepage" }, :descendant => { :tag => "a", :content => /my new home page/ }
  199 + end
  200 +
157 should 'set last_changed_by when creating article' do 201 should 'set last_changed_by when creating article' do
158 login_as(profile.identifier) 202 login_as(profile.identifier)
159 203
test/functional/profile_controller_test.rb
@@ -734,7 +734,7 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -734,7 +734,7 @@ class ProfileControllerTest &lt; ActionController::TestCase
734 end 734 end
735 735
736 should 'see the activities_items paginated' do 736 should 'see the activities_items paginated' do
737 - p1= Person.first 737 + p1 = create_user('some').person
738 ActionTracker::Record.destroy_all 738 ActionTracker::Record.destroy_all
739 40.times{Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))} 739 40.times{Scrap.create!(defaults_for_scrap(:sender => p1, :receiver => p1))}
740 login_as(p1.identifier) 740 login_as(p1.identifier)
@@ -1170,6 +1170,58 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1170,6 +1170,58 @@ class ProfileControllerTest &lt; ActionController::TestCase
1170 assert_redirected_to :controller => 'account', :action => 'login' 1170 assert_redirected_to :controller => 'account', :action => 'login'
1171 end 1171 end
1172 1172
  1173 + should "not index display activities comments" do
  1174 + login_as(profile.identifier)
  1175 + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software')
  1176 + ActionTracker::Record.destroy_all
  1177 + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image})
  1178 + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)}
  1179 + article.reload
  1180 + get :index, :profile => profile.identifier
  1181 + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments'}, :children => {:count => 0 }
  1182 + end
  1183 +
  1184 + should "view more comments paginated" do
  1185 + login_as(profile.identifier)
  1186 + article = TinyMceArticle.create!(:profile => profile, :name => 'An Article about Free Software')
  1187 + ActionTracker::Record.destroy_all
  1188 + activity = ActionTracker::Record.create!(:user_id => profile.id, :user_type => 'Profile', :verb => 'create_article', :target_id => article.id, :target_type => 'Article', :params => {'name' => article.name, 'url' => article.url, 'lead' => article.lead, 'first_image' => article.first_image})
  1189 + 20.times {comment = fast_create(Comment, :source_id => article, :title => 'a comment', :body => 'lalala', :created_at => Time.now)}
  1190 + article.reload
  1191 + assert_equal 20, article.comments.count
  1192 + get :more_comments, :activity => activity.id, :comment_page => 2
  1193 + assert_response :success
  1194 + assert_template '_comment'
  1195 + assert_select_rjs :insert_html do
  1196 + assert_select 'li', 5 # 5 comments per page
  1197 + end
  1198 + end
  1199 +
  1200 + should "not index display scraps replies" do
  1201 + login_as(profile.identifier)
  1202 + Scrap.destroy_all
  1203 + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id)
  1204 + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)}
  1205 + profile.reload
  1206 + get :index, :profile => profile.identifier
  1207 + assert_tag 'ul', :attributes => {:class => 'profile-wall-activities-comments scrap-replies'}, :children => {:count => 0 }
  1208 + end
  1209 +
  1210 + should "view more replies paginated" do
  1211 + login_as(profile.identifier)
  1212 + Scrap.destroy_all
  1213 + scrap = fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id)
  1214 + 20.times {fast_create(Scrap, :sender_id => profile.id, :receiver_id => profile.id, :scrap_id => scrap.id)}
  1215 + profile.reload
  1216 + assert_equal 20, scrap.replies.count
  1217 + get :more_replies, :activity => scrap.id, :comment_page => 2
  1218 + assert_response :success
  1219 + assert_template '_profile_scrap'
  1220 + assert_select_rjs :insert_html do
  1221 + assert_select 'li', 5 # 5 replies per page
  1222 + end
  1223 + end
  1224 +
1173 should 'render empty response for not logged in users in check_membership' do 1225 should 'render empty response for not logged in users in check_membership' do
1174 get :check_membership 1226 get :check_membership
1175 assert_equal '', @response.body 1227 assert_equal '', @response.body
@@ -1331,30 +1383,6 @@ class ProfileControllerTest &lt; ActionController::TestCase @@ -1331,30 +1383,6 @@ class ProfileControllerTest &lt; ActionController::TestCase
1331 assert_equal "Comment successfully added.", assigns(:message) 1383 assert_equal "Comment successfully added.", assigns(:message)
1332 end 1384 end
1333 1385
1334 - should 'display comment in wall if user was removed' do  
1335 - UserStampSweeper.any_instance.stubs(:current_user).returns(profile)  
1336 - article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')  
1337 - to_be_removed = create_user('removed_user').person  
1338 - comment = Comment.create!(:author => to_be_removed, :title => 'Test Comment', :body => 'My author does not exist =(', :source_id => article.id, :source_type => 'Article')  
1339 - to_be_removed.destroy  
1340 -  
1341 - login_as(profile.identifier)  
1342 - get :index, :profile => profile.identifier  
1343 -  
1344 - assert_tag :tag => 'span', :content => '(removed user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-removed'}  
1345 - end  
1346 -  
1347 - should 'display comment in wall from non logged users' do  
1348 - UserStampSweeper.any_instance.stubs(:current_user).returns(profile)  
1349 - article = TinyMceArticle.create!(:profile => profile, :name => 'An article about free software')  
1350 - comment = Comment.create!(:name => 'outside user', :email => 'outside@localhost.localdomain', :title => 'Test Comment', :body => 'My author does not exist =(', :source_id => article.id, :source_type => 'Article')  
1351 -  
1352 - login_as(profile.identifier)  
1353 - get :index, :profile => profile.identifier  
1354 -  
1355 - assert_tag :tag => 'span', :content => '(unauthenticated user)', :attributes => {:class => 'comment-user-status comment-user-status-wall icon-user-unknown'}  
1356 - end  
1357 -  
1358 should 'add locale on mailing' do 1386 should 'add locale on mailing' do
1359 community = fast_create(Community) 1387 community = fast_create(Community)
1360 create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community) 1388 create_user_with_permission('profile_moderator_user', 'send_mail_to_members', community)
test/unit/application_helper_test.rb
@@ -814,6 +814,32 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase @@ -814,6 +814,32 @@ class ApplicationHelperTest &lt; ActiveSupport::TestCase
814 assert_no_match /Test1/, parsed_html 814 assert_no_match /Test1/, parsed_html
815 end 815 end
816 816
  817 + should 'not convert macro if source is nil' do
  818 + profile = create_user('testuser').person
  819 + article = fast_create(Article, :profile_id => profile.id)
  820 + class Plugin1 < Noosfero::Plugin; end
  821 +
  822 + environment = Environment.default
  823 + environment.enable_plugin(Plugin1)
  824 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  825 +
  826 + expects(:convert_macro).never
  827 + filter_html(article.body, nil)
  828 + end
  829 +
  830 + should 'not convert macro if there is no macro plugin active' do
  831 + profile = create_user('testuser').person
  832 + article = fast_create(Article, :profile_id => profile.id)
  833 + class Plugin1 < Noosfero::Plugin; end
  834 +
  835 + environment = Environment.default
  836 + environment.enable_plugin(Plugin1)
  837 + @plugins = Noosfero::Plugin::Manager.new(environment, self)
  838 +
  839 + expects(:convert_macro).never
  840 + filter_html(article.body, article)
  841 + end
  842 +
817 protected 843 protected
818 include NoosferoTestHelper 844 include NoosferoTestHelper
819 845
test/unit/comment_test.rb
@@ -285,22 +285,6 @@ class CommentTest &lt; ActiveSupport::TestCase @@ -285,22 +285,6 @@ class CommentTest &lt; ActiveSupport::TestCase
285 assert_equal [c1,c3], c.reload.children 285 assert_equal [c1,c3], c.reload.children
286 end 286 end
287 287
288 - should "return activities comments as a thread" do  
289 - person = fast_create(Person)  
290 - a = TextileArticle.create!(:profile => person, :name => 'My article', :body => 'Article body')  
291 - c0 = Comment.create!(:source => a, :body => 'My comment', :author => person)  
292 - c1 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person)  
293 - c2 = Comment.create!(:reply_of_id => c1.id, :source => a, :body => 'bla', :author => person)  
294 - c3 = Comment.create!(:reply_of_id => c0.id, :source => a, :body => 'bla', :author => person)  
295 - c4 = Comment.create!(:source => a, :body => 'My comment', :author => person)  
296 - result = a.activity.comments_as_thread  
297 - assert_equal c0, result[0]  
298 - assert_equal [c1, c3], result[0].replies  
299 - assert_equal [c2], result[0].replies[0].replies  
300 - assert_equal c4, result[1]  
301 - assert result[1].replies.empty?  
302 - end  
303 -  
304 should 'provide author url for authenticated user' do 288 should 'provide author url for authenticated user' do
305 author = Person.new 289 author = Person.new
306 author.expects(:url).returns('http://blabla.net/author') 290 author.expects(:url).returns('http://blabla.net/author')
vendor/plugins/action_tracker_has_comments/init.rb
@@ -3,22 +3,13 @@ @@ -3,22 +3,13 @@
3 Rails.configuration.to_prepare do 3 Rails.configuration.to_prepare do
4 ActionTracker::Record.module_eval do 4 ActionTracker::Record.module_eval do
5 5
6 - has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy, :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC', :counter_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments}' 6 + has_many :comments, :class_name => 'Comment', :foreign_key => 'source_id', :dependent => :destroy,
  7 + :finder_sql => 'SELECT * FROM comments WHERE #{conditions_for_comments} ORDER BY created_at ASC',
  8 + :counter_sql => 'SELECT COUNT(*) FROM comments WHERE #{conditions_for_comments}'
7 9
8 def conditions_for_comments 10 def conditions_for_comments
9 type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id]) 11 type, id = (self.target_type == 'Article' ? ['Article', self.target_id] : [self.class.to_s, self.id])
10 - "source_type = '#{type}' AND source_id = '#{id}'"  
11 - end  
12 -  
13 - def comments_as_thread  
14 - result = {}  
15 - root = []  
16 - self.comments.each do |c|  
17 - c.replies = []  
18 - result[c.id] ||= c  
19 - c.reply_of_id.nil? ? root << c : result[c.reply_of_id].replies << c  
20 - end  
21 - root 12 + "source_type = '#{type}' AND source_id = '#{id}' AND reply_of_id IS NULL"
22 end 13 end
23 14
24 end 15 end